[英]Convert a 64bit integer to an array of 7bit-characters
假设我有一个函数vector<unsigned char> byteVector(long long UID)
,返回一个64位整数UID的字节表示形式作为vector
。 此向量随后用于将数据写入文件。
现在,因为我决定要使用Python读取该文件,所以我必须遵守utf-8标准,这意味着我只能使用每个char的前7位 。 如果最高有效位为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]);
}
当然,这并不工作了,作为约束“HBit可能不是1”中的每一个的最大值限制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,我很抱歉)将满足。 所以:
如何将64位整数转换为10个7位整数的向量?
这可能是太多的优化,但是对于这个问题可能有一些非常酷的解决方案(可能使用移位运算符),我对此很感兴趣。
您可以使用移位来获取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 。 在这种情况下,您将需要再一个字符(总共11个)来编码64位。
我建议使用汇编语言。
许多汇编语言都提供了将位移入“备用”进位位并将进位移入寄存器的指令。 C语言没有方便或有效的方法来执行此操作。
算法:
for i = 0; i < 7; ++i
{
right shift 64-bit word into carry.
right shift carry into character.
}
您还应该研究使用std::bitset
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.