为什么看似空的文件和字符串也会生成 md5sum 值?

63

考虑以下内容:

% md5sum /dev/null
d41d8cd98f00b204e9800998ecf8427e  /dev/null
% touch empty; md5sum empty
d41d8cd98f00b204e9800998ecf8427e  empty
% echo '' | md5sum
68b329da9893e34099c7d8ad5cb9c940  -
% perl -e 'print chr(0)' | md5sum
93b885adfe0da089cdf634904fd59f71  -
% md5sum ''
md5sum: : No such file or directory

首先,我对所有这些命令的输出感到惊讶。如果有什么不同,我会期望它们的总和都是相同的。


你可以使用od -tax1命令来查看你的示例3和4实际上并不是空文件。例如:echo '' | od -tax1 - pabouk - Ukraine stay strong
3个回答

115

"nothing"(一个零长度的字符流)的md5sum是d41d8cd98f00b204e9800998ecf8427e,这是您在前两个示例中看到的。

第三个和第四个示例正在处理单个字符。在“echo”案例中,它是一个换行符,即

$ echo -ne '\n' | md5sum
68b329da9893e34099c7d8ad5cb9c940 -
在 Perl 的例子中,这是一个值为 0x00 的单个字节。
$ echo -ne '\x00' | md5sum
93b885adfe0da089cdf634904fd59f71 -

您可以使用“echo”来复制空校验和,方法如下:

$ echo -n '' | md5sum
d41d8cd98f00b204e9800998ecf8427e -

...并使用Perl如下:

$ perl -e 'print ""' | md5sum
d41d8cd98f00b204e9800998ecf8427e  -
在这四种情况下,你应该期望使用相同数据进行校验和时得到相同的输出,但不同的数据应该会产生截然不同的校验和(这就是整个目的——即使只有一个字符不同)。

4
"perl -e ''" 可以翻译为“使用Perl运行空字符串”。 - minmaxavg
或者 md5sum < /dev/null - gerrit

24

为什么看似空文件和字符串会产生md5校验和?

因为md5sum中的"sum"有点误导人。 它不像CRC32校验和一样对空文件为零。

MD5是消息摘要算法之一,您可以将其想象为一个箱子,它根据其内部状态生成固定长度的随机值(哈希),而这个内部状态会通过输入的数据来改变。

该箱子的内部状态是预定义的,即使在输入任何数据之前,它也会产生随机的哈希值。 对于MD5,它恰好是d41d8cd98f00b204e9800998ecf8427e


6
更准确地说,MD5会在消息末尾添加一个填充块。因此,哈希值是通过对该填充块进行散列函数运算得出的,而不是精确的初始状态。 - nneonneo

3
没什么好惊讶的。前两个命令会产生空输入,用于计算md5sum值。echo 命令会产生一个换行符(echo -n ''应该会产生空输出;我这里没有Linux机器可以验证)。perl 命令会产生一个零字节(不要与以零字节结尾的C语言字符串混淆)。最后一个命令是在寻找文件名为空字符串的文件。

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