如何在C ++中将64位整数转换为大端字节数组

时间:2014-05-03 21:29:46

标签: c++ hash append sha256 endianness

(这是Padding the message in SHA256的后续问题。)

(我正在尝试用C ++实现SHA-256哈希函数。我这样做纯粹是为了娱乐和学习目的。)

我的字符串message的长度为message_length。我在字符串后面添加了1位,然后是0 s,这样字符串的长度现在是448位mod 512位。

我现在需要将带有message_length的字符串作为64位大端整数附加到字符串中,但我无法弄清楚如何在C ++中执行此操作。

为了论证,让我们说message_length是3个字节= 24位。十六进制的24是18,所以我需要将00 00 00 00 00 00 00 18附加到字符串。

所以我想要的是一个将整数3转换为字符串00 00 00 00 00 00 00 18的函数,以便我可以追加它。

我的问题归结为

  

如何在C ++中将64位整数转换为大端字节数组

1 个答案:

答案 0 :(得分:2)

修改:我只是重新阅读您的问题(打算编辑它)。我想你误解了SHA256希望你使用的格式。消息长度为24时,不需要附加字符串00 00 00 00 00 00 00 18(每个字节十六进制编码并用空格分隔),而是需要附加原始字节0x00,0x00,0x00,0x00,0x00,0x00,0x00和0x18。它们不代表任何可打印的字符。请参阅下面的获取这些字节的方法。我的示例使用一个整数,其字节表示恰好只包含可打印字符(ASCII格式)。

顺便说一句,你填充448位的原因是你在512位的整个块大小中剩下64位,所以你可以把消息长度的大端编码放在那里。


您可以使用num提取num>>(8*i) & 0xff的单个字节,您将获得i=0的最低有效字节和无符号长(64位)的最高有效字节i=7 1}}。迭代所有位置,你可以得到每个字节:

   unsigned long num = 0x626967656e646961L;
   //Store big endian representation in a vector:
   std::vector<unsigned char> bigEndian;
   for(int i=7; i>=0; i--){
      bigEndian.push_back( (num>>(8*i)) & 0xff );
   }

如果您需要它作为字符串,您可以使用字符串的迭代器构造函数转换它:

   std::string bigEndianString(bigEndian.begin(),bigEndian.end());

包含测试输出的完整代码:

#include <iostream>
#include <string>
#include <vector>
int main() {
   unsigned long num = 0x626967656e646961L;

   //Store big endian representation in a vector:
   std::vector<unsigned char> bigEndian;
   for(int i=7; i>=0; i--){
      bigEndian.push_back( (num>>(8*i)) & 0xff );
   }

   //Convert vector to string:
   std::string bigEndianString(bigEndian.begin(),bigEndian.end());

   //Test correctness:
   for(std::vector<unsigned char>::const_iterator it = bigEndian.begin(); it != bigEndian.end(); ++it) {
       std::cout << std::hex << (int)*it << ' ';
   }
   std::cout << std::endl << bigEndianString << std::endl;

}