【问题标题】:MD5 hash discrepancy between Python and PHP?Python和PHP之间的MD5哈希差异?
【发布时间】:2011-08-08 20:01:50
【问题描述】:

我正在尝试创建二进制文件(flv/f4v 等)的校验和,以验证服务器和客户端计算机之间的文件内容。在客户端计算机上运行的应用程序是基于 python 的,而服务器使用的是 PHP。

PHP代码如下:

$fh = fopen($filepath, 'rb');
$contents = fread($fh, filesize($filepath));
$checksum = md5(base64_encode($contents));
fclose($fh);

Python代码如下:

def _get_md5(filepath):
    fh = open(filepath, 'rb')
    md5 = hashlib.md5()
    md5.update(f.read().encode('base64'))
    checksum = md5.hexdigest()
    f.close()
    return checksum

在我正在测试的特定文件上,PHP 和 Python md5 哈希字符串分别如下:

cfad0d835eb88e5342e843402cc42764
0a96e9cc3bb0354d783dfcb729248ce0

服务器运行 CentOS,而客户端是 MacOSX 环境。我将不胜感激任何帮助理解为什么两者会产生不同的哈希结果,或者如果它是我忽略的东西(我对 Python 比较陌生......)。谢谢!

[事后分析:问题归根结底是 Python 和 PHP 的 base64 编码变体之间的差异。 MD5 在两个脚本平台之间的工作方式相同(至少在 Python 中使用 .hexdigest())。]

【问题讨论】:

  • 我很确定文件的base64表示不同,而不是md5算法,你能检查一下吗?
  • 为什么要使用 base64 呢?为什么不只是 md5 原始二进制文件?
  • 你有什么理由首先对文件的内容进行base64编码? md5 函数也会很高兴地处理原始二进制数据。正如 htf 所建议的,从等式中删除 base64 并看看会发生什么。如果出于某种原因,python 和 php 行包装 base64 数据(例如,用于电子邮件插入),并选择了不同的包装点,那会抛出散列并且你永远不会知道,因为你没有检查 base64 输出平等优先。
  • 感谢大家的及时回复!我去掉了 base64 编码步骤,现在它似乎可以完美地工作了。我什至不知道为什么我首先使用 base64 编码,我想我可能是为了规范化内容而这样做的,它不可避免地最终变得更糟,哈哈。问题解决了!谢谢!
  • @user715565 在 SO 上将问题标记为“已解决”的方法是接受最能解决问题的答案(单击答案分数下的复选标记)

标签: php python md5


【解决方案1】:

我宁愿假设 base64 实现不同。

编辑

PHP:

php -r 'var_dump(base64_encode(str_repeat("x", 10)));'
string(16) "eHh4eHh4eHh4eA=="

Python(注意尾随的换行符):

>>> ("x" * 10).encode('base64')
'eHh4eHh4eHh4eA==\n'

【讨论】:

  • 而问题的cmets提出了另一个重要的观点:你不需要base64,如果你想要一个哈希,你可以直接对字符串进行哈希。
【解决方案2】:

PHP 和 python 使用不同的 base64 风格:

【讨论】:

    【解决方案3】:

    问题似乎是你对文件数据进行base-64编码,改变了二进制数据的结构,在php中我相信它没有对文件进行base_64编码。

    试一试:

    def md5_file(filename):
        //MD5 Object
        crc = hashlib.md5()
        //File Pointer Object
        fp = open(filename, 'rb')
    
        //Loop the File to update the hash checksum
        for i in fp:
            crc.update(i)
    
        //Close the resource
        fp.close()
    
        //Return the hash
        return crc.hexdigest()
    

    在 PHP 中使用 md5_file 并查看是否相应地工作。

    python 取自:http://www.php2python.com/wiki/function.md5-file/

    【讨论】:

      【解决方案4】:

      Python 在使用 .encode 时会在字符串中附加一个换行符 '\n',因此 md5 函数的输入字符串是不同的。 Python 错误跟踪器中的This 问题详细解释了它。其要点见下文:

      >>> import base64
      >>> s='I am a string'
      >>> s.encode('base64')
      'SSBhbSBhIHN0cmluZw==\n'
      >>> base64.b64encode(s)
      'SSBhbSBhIHN0cmluZw=='
      >>> s.encode('base64')== base64.b64encode(s)+'\n'
      True
      

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 2012-01-21
        • 1970-01-01
        • 2010-11-02
        • 2018-08-24
        • 1970-01-01
        • 2015-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多