将64位整数转换为7位字符的数组

时间:2014-04-05 17:54:12

标签: c++ c arrays long-integer

假设我有一个函数vector<unsigned char> byteVector(long long UID),返回UID的字节表示,64位整数,作为vector。该向量稍后用于将此数据写入文件。

现在,因为我决定用Python读取该文件,所以我必须遵守utf-8标准,这意味着我可以only use the first 7bits of each char。如果最高有效位为1,我就不能将其解码为字符串,因为它们只支持ASCII字符。此外,我必须通过命令行界面将这些字符串传递给其他进程,命令行界面也只支持ASCII字符集。

在出现这个问题之前,我将64位整数分成8个独立字节的方法如下,这非常有效:

vector<unsigned char> outputVector = vector<unsigned char>();
unsigned char * uidBytes = (unsigned char*) &UID_;
for (int i = 0; i < 8; i++){
    outputVector.push_back(uidBytes[i]);
}

当然,这不再适用,因为约束&#34; HBit可能不是1&#34;将每个unsigned char的最大值限制为127。 我现在最简单的选择当然是用这个替换一个push_back来电:

outputVector.push_back(uidBytes[i] / 128);
outputVector.push_back(uidBytes[i] % 128);

但这似乎有点浪费,因为每个unsigned char对中的第一个只能是0或1而我会浪费一些空间(6个字节),否则我就可以使用它。

由于我需要保存64位,并且每个字节可以使用7位,所以我需要64 // 7 + 64%7 = 10个字节。

它真的不多(我写的文件都没有达到1kB标记),但之前我使用的是8个字节,现在使用16个十(不是9,I&I)似乎有点浪费#39;对不起)就够了。所以:

如何将64位整数转换为10个7位整数的向量?

这可能是太多的优化,但是对于这个问题可能有一些非常酷的解决方案(可能使用移位运算符),我真的很想看到它。

2 个答案:

答案 0 :(得分:4)

您可以使用位移来获取64位整数的7位数。但是,你需要10个7位整数,9个是不够的:9 * 7 = 63,有点短。

  std::uint64_t uid = 42; // Your 64-bit input here.
  std::vector<std::uint8_t> outputVector;

  for (int i = 0; i < 10; i++)
  {
    outputVector.push_back(uid >> (i * 7) & 0x7f);
  }

在每次迭代中,我们将输入位移位7的倍数,并屏蔽掉7位部分。 8位数字的最高位将为零。注意,向量中的数字是“反向的”:最低有效位具有最低的索引。但是,如果您以正确的方式解码部件,则无关紧要。解码可以按如下方式进行:

std::uint64_t decoded = 0;
for (int i = 0; i < 10; i++)
{
  decoded |= static_cast<std::uint64_t>(outputVector[i]) << (i * 7);
}

请注意,将结果向量解释为UTF-8编码文本似乎是一个坏主意:序列仍然可以包含控制字符和\0。如果要以可打印字符对64位整数进行编码,请查看base64。在这种情况下,您将需要一个字符(总共十一个)来编码64位。

答案 1 :(得分:1)

我建议使用汇编语言。

许多汇编语言都有将位转换为&#34;备用&#34;进位并将进位位移入寄存器。 C语言没有方便或有效的方法来执行此操作。

算法:

for i =  0; i < 7; ++i
{
  right shift 64-bit word into carry.
  right shift carry into character.
}

您还应该考虑使用std::bitset