与c++中的字节、块、en-/解码混淆
confused with bytes, blocks, en-/decoding in c++
我有一个64字节的块,希望在末尾附加一个64位(8字节)的数据块。
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]]
从附录到填充的最后8字节的memcpy 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
};
我不知道这里怎么了!?!?
你能帮我吗?
appendix[1] = 0x000000ff;
// [[00000000000000000000000000000000][00000000000000000000000011111111]]
您正在对字节顺序(endianness)进行假设。你不能做出这样的假设。根据体系结构的字节顺序,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或其他提供它们的平台上,则可以使用htole32
和le32toh
函数转换为正确的字节顺序。在另一个平台上,您可能需要自己实现它们。
因此,就我所能理解的RFC1321而言,我需要原始消息(文件)大小的64位整数表示。文件大小为64字节。在64位整数中,值64是二进制的:
0000000000000000000000000000000000000000000000000000000001000000
或:
0000001000000000000000000000000000000000000000000000000000000000
我对两者都有解码功能,但我不知道哪一个对md5正确?
您应该看看Endianless。你的选择是big-endian。
- 无法解码base64+deflate数据
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 使用已使用 java 编码的 openssl 解码数据
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- 从原始字节解码协议缓冲区(以 C++为单位)
- FFmpeg——使用硬件加速进行视频解码
- 如何从WIC解码器确定自上而下/自下而上?
- 使用公钥加密消息:BER 解码错误
- 在CRC-16 CCITT中将数据从二进制解码为文本,我应该输入一个码字,使用CRC生成器进行编码
- 在 GLFW 窗口中显示 FFMPEG 解码帧
- 如何将 MJPEG 解码为原始 RGB(或 YUV)数据
- 编译时 Base64 解码 C++
- 解码H264流时如何跳过帧?
- 无法在 HEVC 解码器上设置输出类型 IMFTransform
- pyserial arduino 字节阵列解码问题
- 将帧从 h264 流解码到 OpenCV Mat
- C++ std::locale( "en" ) 在 iOS 上引发异常
- 连接无线电流和 MP3 解码器
- 与c++中的字节、块、en-/解码混淆