2015-11-04 31 views
1

我有一个64字节的块,并希望在最后附加一个64位(8字节)数据块。与C++中的字节,块,en- /解码混淆

typedef unsigned char uint1; // 1 Byte 
typedef unsigned int uint4; // 4 Byte 

// The 64 Byte-Block: 
int BLOCKSIZE=64; 
static uint1 padding[BLOCKSIZE] = { 
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
}; 
// [[10000000][00000000].........[00000000]] 


// The 64 Bit (8 Byte-Block): 
uint4 appendix[2] = {}; 
appendix[1] = 0x000000ff; 
// [[00000000000000000000000000000000][00000000000000000000000011111111]] 

的memcpy后,从8个字节附录的最后8个字节的填充的

memcpy(&padding[56], &appendix, 8); 

它看起来像

static uint1 padding[BLOCKSIZE] = { 
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0 
    }; 

,但不应该是这个样子?

static uint1 padding[BLOCKSIZE] = { 
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff 
    }; 

我不知道这里有什么问题!?!?

你能帮我吗?

+0

uint1是什么? C不支持位寻址对象。并且不要为C++问题添加C标签!这些是不同的语言。 – Olaf

+0

对不起,我更正了我的问题 – tbol

+0

您位于little-endian平台上,并且首先保存LSB(即底部字节在先)。 顺便说一句,使用long或uint32_t 4个字节的整数,而不是int。 –

回答

1
appendix[1] = 0x000000ff; 
// [[00000000000000000000000000000000][00000000000000000000000011111111]] 

您对字节顺序(字节顺序)做出了假设。你不能做出这样的假设。根据architechture的字节顺序,appendix也可以表示这样的:

// [[00000000000000000000000000000000][11111111000000000000000000000000]] 

如果要专门设置的最后一个字节,那么你需要在字节,不支持多字节整数操作。像这样的例子:

uint1 appendix[8] = {}; 
appendix[7] = 0xff; 

如果你确实需要的最后8个字节来表示两个4字节的整数,你的代码是在这方面正确的,只有你对内存应该是什么样子的假设是错误的。

如果整数必须以特定的字节顺序通过网络发送,那么您必须适当地转换它。 POSIX提供htonl,它完全是它的姐妹功能。这些功能也由msvc提供。

你也假设unsigned int是4个字节。不保证是。如果您需要4字节的整数,请使用int32_t

更新:

我的目标是实现MD5,我需要附加一个文件的长度的64位代表。

根据rfc1321

...的 字节序列可以被解释为32位字的序列,其中的四个字节每个 连续组被解释为与字首先给出 低位(最低有效位)字节。

MD5是小尾数。因此,在不转换字节顺序的情况下编写2 * 4数组只能在小端处理器上正常工作。

我推荐使用8 * 1字节数组,以便您可以完全按照规范要求控制字节的顺序。或者,如果您在Linux或其他提供它们的平台上,则可以使用htole32le32toh函数转换为正确的字节顺序。在另一个平台上,您可能需要自行实施它们。

+0

好的,thx。我的问题是我不知道哪个是正确的。我现在很困惑。我的目标是实现MD5,我需要附加一个文件长度的64位表示。如果有比使用2 * 4字节数组更好的方式,请告诉我。其实我会尝试两种方式。首先,一个2 * 4字节的数组和一个64位的整数。我尝试了两种方法,并在追加后比较结果。 – tbol

+0

@tbol我更新了我的回答以解决您的评论。 – user2079303

+0

那么什么是正确的二进制表达式,如果我有一个8字节大小的文件,存储在一个64位整数?我认为它是:[000000(56零)......... 01000000]和8 * 1字节表示应该看起来像这样:[00000000] [00000000] ... [01000000],对吗? – tbol

-2

你应该看看Endianless。你的选择在这里是大端的。

-1

所以,据我所知,RFC1321我需要原始消息(文件)大小的64位整数表示法。文件大小是64字节。在64位整数值为64是二进制之一:

0000000000000000000000000000000000000000000000000000000001000000 

或:

0000001000000000000000000000000000000000000000000000000000000000 

我有两个解码funcitons,但我不知道这是正确的MD5?

+0

为什么降低我的答案?对不起,我还没有第一时间了解所有信息:/ – tbol