简体   繁体   English

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

[英]How can I convert a 64bit integer to a big-endian byte array in C++

(This is a follow-up question to Padding the message in SHA256 .) (这是在SHA256中填充消息的后续问题。)

(I am trying to implement the SHA-256 hash function in C++. I am doing this purely for fun and learning purposes.) (我正在尝试在C ++中实现SHA-256哈希函数。我这样做纯粹是出于娱乐和学习目的。)

I have my string message with length message_length . 我有长度为message_length字符串message I have appended the string with the bit 1 followed by 0 s so that the length of the string is now 448 bits mod 512 bits. 我在字符串后附加了位10 s,以使字符串的长度现在是448位和512位。

I now need to append the string with the message_length as 64-bit big-endian integer to the string, but I can't quite figure out how to do this in C++. 现在,我需要将message_length的字符串作为64位big-endian整数附加到字符串中,但是我不太清楚如何在C ++中执行此操作。

For sake of argument then, lets say message_length is 3 bytes = 24 bits. 那么为了论证,可以说message_length为3个字节= 24位。 24 in hex is 18 , so I would need to append 00 00 00 00 00 00 00 18 to the string. 十六进制的24是18 ,因此我需要将00 00 00 00 00 00 00 18附加到字符串中。

So what I would like is a function that converts the integer 3 into the string 00 00 00 00 00 00 00 18 so that I can append this. 所以我想要的是一个将整数3转换为字符串00 00 00 00 00 00 00 18的函数,以便我可以附加它。

My question boils down to 我的问题归结为

How can I convert a 64bit integer to a big-endian byte array in C++ 如何在C ++中将64位整数转换为大端字节数组

Edit: I just reread your question (in the intend to edit it). 编辑:我只是重新阅读了您的问题(打算进行编辑)。 I think you misunderstood the format SHA256 expects you to use. 我认为您误解了SHA256希望您使用的格式。 Instead of appending the string 00 00 00 00 00 00 00 18 (each byte hex encoded and separated by spaces) for a message length of 24 you need to append the raw bytes 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 and 0x18. 不需要为消息长度附加字符串00 00 00 00 00 00 00 18 (每个字节用十六进制编码并用空格分隔),而是附加原始字节0x00、0x00、0x00、0x00、0x00、0x00、0x00和为0x18。 They do not represent any printable characters. 它们不代表任何可打印字符。 See below for a way to get these bytes. 有关获取这些字节的方法,请参见下文。 My example uses an integer whose byte representation happens to contain only printable characters (in ASCII). 我的示例使用一个整数,其字节表示恰好仅包含可打印字符(ASCII)。

Btw., the reason you pad to 448 bits is that you have 64 bits left in the full block size of 512 bits so you can put the big-endian encoding of the message length in there. 顺便说一句,填充到448位的原因是,在512位的完整块大小中还剩下64位,因此可以在其中放入消息长度的大端编码。


You can extract a single byte of num using num>>(8*i) & 0xff where you will get the least significant byte for i=0 and the most significant byte of an unsigned long (64bit) with i=7 . 您可以提取单个字节num使用num>>(8*i) & 0xff ,您将得到至少显著字节, i=0和一个unsigned long(64位)的最显著字节与i=7 Iterating through all positions you can get each byte: 遍历所有位置,您可以获得每个字节:

   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 );
   }

If you need it as a string you can convert it using the iterator constructor of a string: 如果需要将其作为字符串,则可以使用字符串的迭代器构造函数将其转换:

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

Complete code with test output: 带有测试输出的完整代码:

#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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM