md5(文件内容作为字符串)是否等于md5_file(/path/to/file)?

34
如果我这样做:
```php ```
...是否总会产生与以下代码相同的哈希值?
```php ```

5
如果文件中包含一个字节顺序标记,而字符串中没有,那么哈希值就不相等。无法确定,但这可能是情况之一。关于字节顺序标记的详细信息,请参阅链接。 - vcsjones
4
作为对已删除评论的回应,我可以尝试自己去尝试。只是我担心如果我得到一个匹配并开始比较md5()和md5_file(),可能在后续出现问题,导致产生不同的哈希值 - 可能与php_ini指令或一些超出我的理解范围的内容有关,这将是一个令人噩梦般的调试/识别过程。 - Tom
4个回答

35

是的,它们返回相同的结果:

var_dump(md5(file_get_contents(__FILE__)));
var_dump(md5_file(__FILE__));

在我的情况下,它返回了这个:

string(32) "4d2aec3ae83694513cb9bde0617deeea"
string(32) "4d2aec3ae83694513cb9bde0617deeea"

编辑: 查看两个函数的源代码:https://github.com/php/php-src/blob/master/ext/standard/md5.c(第47和76行)。它们都使用相同的函数生成哈希,只是md5_file()函数首先打开文件。

第二次编辑: 基本上,md5_file()函数根据文件内容生成哈希值,而不是根据文件元数据(比如文件名)。这与Linux系统上的md5sum方式相同。 请参见以下示例:

pr@testumgebung:~# echo foobar > foo.txt
pr@testumgebung:~# md5sum foo.txt
14758f1afd44c09b7992073ccf00b43d  foo.txt
pr@testumgebung:~# mv foo.txt bar.txt
pr@testumgebung:~# md5sum bar.txt
14758f1afd44c09b7992073ccf00b43d  bar.txt

3

md5_file 命令只是使用 md5 算法对文件内容进行哈希。

如果您参考旧的 md5_file PHP 实现(但原理仍然是相同的)源代码

function php_compat_md5_file($filename, $raw_output = false)
{
// ...
// removed protections

 if ($fsize = @filesize($filename)) {
        $data = fread($fh, $fsize);
    } else {
        $data = '';
        while (!feof($fh)) {
            $data .= fread($fh, 8192);
        }
    }

    fclose($fh);

    // Return
    $data = md5($data);
    if ($raw_output === true) {
        $data = pack('H*', $data);
    }

    return $data;
}

如果你使用md5对任意字符串或内容进行哈希,针对相同的编码和文件内容,你总会得到与md5_file相同的结果。
在这种情况下,如果你使用file_get_content()对文件内容进行md5哈希,或者使用md5_file甚至是使用与文件内容相同的内容进行md5命令,你总会得到相同的结果。
例如,你可以更改一个文件的文件名,对于两个不同的文件,只要它们的内容相同,它们就会产生相同的md5哈希值。
举例来说,假设有两个文件1.txt和2.txt,它们都包含“stackoverflow”(不包括引号)。
md5_file("1.txt");
md5_file("2.txt");

将输出

73868cb1848a216984dca1b6b0ee37bc

如果你执行md5("stackoverflow")或者是md5(file_get_contents("1.txt"))或者是md5(file_get_contents("1.txt")),都会得到完全相同的结果。


你所提到的源代码是一个旧的PHP函数实现。但是解释很好。 - prehfeldt
你有新的链接吗?我没有免费的网络访问,这里有很多网站都被封锁了。如果你有新的来源,我会更新我的帖子。 - Pier-Alexandre Bouchard
@pier-alexandre-bouchard在他自己的回答中发布了有关PHP源代码的链接。 :) - damianb
@damianb 我在谈论来自PHP源代码的md5_file实现。 - Pier-Alexandre Bouchard
在PHP中没有更新的实现,因为它已成为PHP分发的一部分,并在几年前被重写为C语言。 - prehfeldt

3
基于文件内容,而非文件元数据(如BOM或文件名)。
关于BOM不正确。 BOM是文件内容的一部分,在任何非Unicode文件编辑器中,您都可以看到它的三个字节。

2
这应该是对你引用的答案的评论,而不是单独的答案。 - BHSPitMonkey

2

是的,我已经尝试过几次了。

在我的情况下,结果为:

<?php echo md5(file_get_contents("1.php")) ?>
<br/>
<?php echo md5_file("1.php") ?>

生成输出如下:
660d4e394937c10cd1c16a98f44457c2
660d4e394937c10cd1c16a98f44457c2 

这在两行上看起来是等价的。


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