MD5的二进制模式和文本模式有什么区别?

22
以下是我的测试内容:
...$ md5sum -b roy.html 
f9283ca2833ff7ebb6781ab8d23a21aa *roy.html
...$ md5sum -t roy.html 
f9283ca2833ff7ebb6781ab8d23a21aa  roy.html

这两种模式有什么不同吗?


5
https://unix.stackexchange.com/a/127961 - Greg Dan
1
关于数字保存中使用校验和的注意事项:二进制模式是标准。 - Peter Krauss
2个回答

14

‘-b’ ‘--binary’

  • 将每个输入文件视为二进制文件,以二进制模式读取并输出 “*” 标志。这是 --text 的反义。在不区分二进制和文本文件的系统上(如 GNU),此选项仅将每个输入模式标记为二进制:MD5 校验和不受影响。在像 MS-DOS 这样区分二进制和文本文件的系统上(除了在读取标准输入时标准输入是终端的情况下),此选项是默认值。

‘-t’ ‘--text’

  • 将每个输入文件视为文本,以文本模式读取并输出“ ”标志。这是 --binary 的反义。在不区分二进制和文本文件的系统(如 GNU)上,此选项是默认值。在其他系统上,在读取标准输入时标准输入是终端的情况下,这是默认值。如果使用 --tag,则永远不会默认为此模式。

5
请问您能否提供一个文件的例子,使得该文件的 MD5 校验和与原文件不同? - Flimm
5
我不知道有任何能够做到这一点的MD5校验工具,但在某些编程语言中,各种换行符可能会在读取时自动转换为平台默认值,除非指定了“二进制读取模式”。例如,在Linux上,“\r\n”(Windows换行符)可能会被转换为“\n”,或者在Windows上,“\n”可能会被转换为“\r\n”。 - jpmc26

1

我发现二进制模式和非二进制模式之间有一些有趣的差异。

我的使用场景是为了在AWS S3块存储服务上创建256位AES密钥。这些密钥用于支持服务器端加密(SSE)。我花了几个小时(几乎是几天)来弄清楚为什么我的代码无法与S3交互,从未怀疑过我的密钥可能是问题所在。实际上,生成密钥并不是问题。我能够轻松地生成二进制密钥和二进制密钥的base64编码版本。

问题所在确实让我感到非常惊讶。我对md5并不陌生,几十年来一直使用它而从未出错。但事实证明,我基于二进制密钥生成的md5校验和是错误的。我的第一个指示是它比我看到的工作示例中的字符要多几个。我一直无法创建像示例中那样短的md5校验和,也不知道为什么会有差异。

我发现:

OSX(BSD)的md5没有二进制输入模式的概念。

OSX(BSD)的md5sum有一个用于二进制输入模式的标志,但它不会改变实际输出的哈希值,它只会改变与该哈希相关的元数据。

Alpine Linux的md5确实有二进制输入模式的概念。

Alpine Linux的md5sum没有二进制输入模式的概念。

Debian Linux似乎不存在md5。

Debian Linux的md5sum有一个用于二进制输入模式的标志,但它不会改变实际输出的哈希值,它只会改变与该哈希相关的元数据。

例如,运行时我得到以下输出:

OSX:

openssl rand 32 > key
cat key | md5
936e87c3f08e54d036c7a38dc9dbd540
cat key | md5sum
936e87c3f08e54d036c7a38dc9dbd540  -
cat key | md5sum -b
936e87c3f08e54d036c7a38dc9dbd540 *-

阿尔派 Linux:

openssl rand 32 > key
cat key | md5
915b2c6c3368c19f96e9a79089389c15
cat key | md5 -b
kVssbDNowZ+W6aeQiTicFQ==
cat key | md5sum
915b2c6c3368c19f96e9a79089389c15  -

Debian Linux:

openssl rand 32 > key
cat key | md5sum
a44f9c1d1f7a35f2374ad2987296b54b  -
cat key | md5sum -b
a44f9c1d1f7a35f2374ad2987296b54b *-

我发现AWS S3至少期望的是一个二进制密钥的MD5值,就像阿尔派Linux在这种情况下所做的那样。
cat key | md5 -b
kVssbDNowZ+W6aeQiTicFQ==

我将尝试联系Alpine Linux的Sören Tempel,以了解这些差异的原因。


3
那个 md5 的 -b 标志不是二进制输入模式,而是 base64 输出模式。它只是改变了输出格式;对输入或哈希生成方式没有影响。你只是选择将哈希值进行 base64 编码,而不是 base16(十六进制)编码。 - Zenexer
谢谢,这是最有用的答案!请注意@jpmc26关于多行文件的评论(DOS\r\n在Linux上可能会转换为\n或在文本模式下反向?)。 - Peter Krauss
对于所有关于在数字保存中使用校验和的读者:二进制模式是标准。 - Peter Krauss
1
Linux在C的文本模式下不执行转换,并且在传递给fopen时忽略二进制标志。只有DOS/Windows会在读取时进行从自身的\r\n到\n的转换,写入时则相反。 - Jimmy Hartzell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接