PHP到Python的pack('H')

4 投票
1 回答
2722 浏览
提问于 2025-04-17 18:57

我正在把一个用PHP写的认证库翻译成Python。这些代码都是老旧的,原来的开发者早就不在了。他们用PHP的'pack'命令把字符串转换成十六进制,使用了'H'这个标志。PHP的文档说这个过程是“十六进制字符串,高位优先”。我看到另一个问题(PHP pack的Python等价物)提到可以用binascii.unhexlify(),但每次我传入一个不是十六进制的字符时,它就会报错。

所以我想问,PHP的pack函数对非十六进制字符是怎么处理的?是把它们丢掉,还是有额外的步骤进行转换?在Python中有没有比binascii.unhexlify更好的方法?

比如对'H*'进行pack处理

php -r 'print pack("H*", md5("Dummy String"));' 

返回的结果是

??????=?PW??

在Python中:

secret = binascii.unhexlify( "Dummy String" )
TypeError: Non-hexadecimal digit found

谢谢你的帮助。

[编辑]

所以DJV说得基本正确。我需要先把值转换成md5,不过这就有意思了。在Python中,md5库通过'digest'方法返回的是二进制数据。

在我的情况下,我可以跳过所有binascii的调用,直接使用

md5.md5('Dummy String').digest()

这在PHP中是:

pack("H*", md5("Dummy String"));

挺有意思的,知道这些真不错。

1 个回答

3

我觉得你需要反过来做。"Dummy String" 不是一个有效的十六进制数字。你可以用 hexlify 来处理它:

>>> binascii.hexlify('Dummy String')
'44756d6d7920537472696e67'

但是不能用 unhexlify 来处理。unhexlify 是把一个十六进制字符串转换成它的 ASCII 表示:

>>> binascii.unhexlify('44756d6d7920537472696e67')
'Dummy String'

你需要做的是对这个字符串(在我们的例子中是 "Dummy String")进行 md5 处理,然后用 unhexlify 来处理它的哈希值:

import binascii
import hashlib

the_hash = hashlib.md5('Dummy String').hexdigest()
print the_hash
the_unhex = binascii.unhexlify(the_hash)
print the_unhex

这样就会得到哈希值和解码后的哈希值:

ec041da9f891c09b3d1617ba5057b3f5
ЛLЬ-ю?=¦PWЁУ

注意:虽然输出的结果看起来和你的不完全一样 - "??????=?PW??",但其中的 "PW" 和 "=" 让我很确定这是正确的。

更多信息可以查看 hashlibbinascii

撰写回答