Arm组装和endianness中的MD5哈希

Arm组装和endianness中的MD5哈希,arm,md5,stm32,endianness,cortex-m,Arm,Md5,Stm32,Endianness,Cortex M,我是Arm汇编编程新手。我试图在arm cortex m4 assembly中编写一个执行MD5哈希算法的函数。我遵循这里找到的wiki页面算法 wikipage声明常量A、B、C、D以及数组S和K。所有值都以小尾端显示 关于little endian: 我做了一些研究,似乎在记忆中,整个字符串都是按顺序显示的,好像整个字符串都是大端的。这是因为每个字符都是一个字节。wiki中的值是以小尾数形式声明的,因此在我声明它们之后,它们在内存中显示为大尾数(正常顺序) 我已经完成了MD5散列的预处理。让

我是Arm汇编编程新手。我试图在arm cortex m4 assembly中编写一个执行MD5哈希算法的函数。我遵循这里找到的wiki页面算法

wikipage声明常量A、B、C、D以及数组S和K。所有值都以小尾端显示

关于little endian:

我做了一些研究,似乎在记忆中,整个字符串都是按顺序显示的,好像整个字符串都是大端的。这是因为每个字符都是一个字节。wiki中的值是以小尾数形式声明的,因此在我声明它们之后,它们在内存中显示为大尾数(正常顺序)

我已经完成了MD5散列的预处理。让我向你展示一下“敏捷的棕色狐狸跳过懒狗”这一串在记忆中是什么样子的:

所以54=T,68,=h,。。。等等

这就是我的困惑所在

在消息之后,附加一个1位。这是字节0x80。在此之后,512位的其余部分用零填充,直到最后64位,即消息的长度。如图所示,消息的长度为0x160位。但在内存中,长度是以小端为单位的,因此显示为6001

所以长度是在记忆中的小端点

但是根据维基,常量A、B、C、D和数组K最初是在小端数中声明的

因此,当我在内存中查看它们时,它们显示为正常

所以现在我很困惑!我的长度在内存中以小尾数表示,常量和K数组在内存中以大尾数表示


在内存中查看示例的正确方式是什么

如果我要这样做,我会找到一个MD5库或类,编写一个简单的示例,以获取我想要散列的文本,然后让编译器为我需要的ARM部件生成程序集

你可以考虑一个MaB[1 ]或一个ARDUINO(2)版本。

[1]

[2]

如果我要这样做,我会找到一个MD5库或类,写一个简单的例子来获取我想要散列的文本,然后让编译器为我需要的ARM部件生成程序集

你可以考虑一个MaB[1 ]或一个ARDUINO(2)版本。

[1]

[2] 将ASCII字符串描述为big-endian并不是真的。Endianness仅适用于多字节值,因此ASCII字符串没有Endianness,因为它们只是字节数组。例如,如果您有一个16位数字的数组,那么endianness将分别应用于数组中的每个值,而不是元素的顺序

您的问题的真正答案是,当以这种方式组织“原始”内存数据时,没有简单的方法可以查看这些数据。大多数调试器都有可变的手表,可用于以类型感知的方式查看内存位置的内容,这通常更容易;例如,您可以告诉watch窗口,
K
指向一个64字节的字符串,
K+56
指向一个小的endian 64位无符号整数,然后这些值将被正确解释和报告


更一般地说,在小端系统中解释“原始”内存数据通常比较困难,因为知道要交换哪些字节以将值放入易于人类读取的顺序依赖于知道每个值的长度,而这些信息在运行时并不存在。这是little-endian系统的缺点,优点是强制转换指针不会改变其绝对值,因为无论数据类型有多大,指针总是指向最低有效字节。

将ASCII字符串描述为大端字节并不是真的。Endianness仅适用于多字节值,因此ASCII字符串没有Endianness,因为它们只是字节数组。例如,如果您有一个16位数字的数组,那么endianness将分别应用于数组中的每个值,而不是元素的顺序

您的问题的真正答案是,当以这种方式组织“原始”内存数据时,没有简单的方法可以查看这些数据。大多数调试器都有可变的手表,可用于以类型感知的方式查看内存位置的内容,这通常更容易;例如,您可以告诉watch窗口,
K
指向一个64字节的字符串,
K+56
指向一个小的endian 64位无符号整数,然后这些值将被正确解释和报告


更一般地说,在小端系统中解释“原始”内存数据通常比较困难,因为知道要交换哪些字节以将值放入易于人类读取的顺序依赖于知道每个值的长度,而这些信息在运行时并不存在。这是little endian系统的缺点,优点是强制转换指针不会改变其绝对值,因为无论数据类型有多大,指针总是指向最低有效字节。

编程语言和体系结构与此无关。您正试图从字符串中准备32位值

"The Quick Brown Fox Jumps Over The Lazy Dog."
作为ASCII字符串,字节在十六进制中如下所示:

54 68 65 20 51 75 69 63 6B 20 42 72 6F 77 6E 20 46 6F 78 20 4A 75 6D 70 73 20 4F 76 65 72 20 54 68 65 20 4C 61 7A 79 20 44 6F 67 2E
但是md5是关于数据字符串的,不是吗?更多关于这一点在一点

你必须小心endianness。一般来说,人们都在谈论字节发送更大的数量(字节的地址从顶部或底部、大端或小端开始)。16位、32位或64位等。最初讨论长度的64位数量:

0x1122334455667788
当以递增地址顺序查看字节列表时,小尾端(就一般理解而言)是

所以

会是

60 01 00 00 00 00 00 00
下一个问题是你的字符串。它应该以0x54686520开头,还是应该以0x20656854或0x63697551开头

我相信维基百科上的文字

The MD5 hash is calculated according to this algorithm. All values are in little-endian.

//Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
那么您的最后(唯一)块应该是

0x20656854
0x63697551
0x7242206B
0x206E776F
0x20786F46
0x706D754A
0x764F2073
0x54207265
0x4C206568
0x20797A61
0x2E676F44
0x00000080
0x00000000
0x00000000
0x00000160
0x00000000
使用我在网上找到的md5源代码例程和usi
60 01 00 00 00 00 00 00
The MD5 hash is calculated according to this algorithm. All values are in little-endian.

//Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
0x20656854
0x63697551
0x7242206B
0x206E776F
0x20786F46
0x706D754A
0x764F2073
0x54207265
0x4C206568
0x20797A61
0x2E676F44
0x00000080
0x00000000
0x00000000
0x00000160
0x00000000
ec60fd67aab1c782cd3f690702b21527
54 68 65 20 becomes 0x20656854 0x000000000000160 becomes 0x00000160, 0x00000000.