【问题标题】:Will md5(file_contents_as_string) equal md5_file(/path/to/file)?md5(file_contents_as_string) 会等于 md5_file(/path/to/file) 吗?
【发布时间】:2012-05-31 02:50:24
【问题描述】:

如果我这样做:

<?php echo md5(file_get_contents("/path/to/file")) ?>

...这将始终产生与以下相同的哈希:

<?php echo md5_file("/path/to/file") ?>

【问题讨论】:

  • 嗯,不能肯定,但如果文件包含byte order mark 并且字符串不包含,那么哈希值将不相等。
  • [回应已删除的评论]我可以自己尝试一下。我只是担心如果我得到一个匹配并且我开始比较 md5() 和 md5_file() 可能会有问题产生不同的哈希 - 可能与 php_ini 指令或我头上的一些类似的东西有关成为调试/识别的噩梦。

标签: php md5 md5-file


【解决方案1】:

是的,它们返回相同:

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

【讨论】:

    【解决方案2】:

    md5_file 命令只是用 md5 散列文件的 内容

    如果参考旧的md5_file PHP实现(但原理还是一样)source

    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 相同的结果(对于相同的编码和文件内容)。

    在这种情况下,如果您通过 md5 对带有 file_get_content() 的文件内容进行哈希处理,或者如果您使用 md5_file 或者即使您使用与文件内容相同的 md5 命令,您将始终得到同样的结果。

    例如,您可以更改一个文件的文件名,对于两个不同的文件,具有相同的内容,它们将产生相同的 md5 哈希。

    例如: 考虑两个包含“stackoverflow”(不带引号)的文件,名为 1.txt 和 2.txt

    md5_file("1.txt");
    md5_file("2.txt");
    

    会输出

    73868cb1848a216984dca1b6b0ee37bc
    

    md5("stackoverflow")md5(file_get_contents("1.txt"))md5(file_get_contents("1.txt")). 将得到完全相同的结果

    【讨论】:

    • 您所指的来源是该函数的旧 PHP 实现。但是解释很好。
    • 你有新链接吗?我没有免费的互联网接入,所以很多网站都被屏蔽了。如果你有新的来源,我会更新我的帖子。
    • @pier-alexandre-bouchard 他在自己的答案中发布了指向相关 php 源代码的链接。 :)
    • @damianb 我说的是 PHP 源代码中的 PHP md5_file 实现。
    • PHP 中没有更新的实现,因为它成为 PHP 发行版的一部分,并在几年前用 C 重写。
    【解决方案3】:

    基于文件内容,而不是像 BOM 或文件名这样的文件元数据

    关于 BOM 的说法不正确。 BOM 是文件内容的一部分,你可以在任何非 unicode 文件编辑器中看到它的三个字节。

    【讨论】:

    • 这应该是对您引用的答案的评论,而不是单独的答案。
    【解决方案4】:

    是的,我试了好几次。 就我而言,结果为:

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

    产生输出为:

    660d4e394937c10cd1c16a98f44457c2
    660d4e394937c10cd1c16a98f44457c2 
    

    这在两条线上似乎是等价的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多