Ruby 解压到 Python
Posted
技术标签:
【中文标题】Ruby 解压到 Python【英文标题】:Ruby unpack to Python 【发布时间】:2012-07-12 08:13:09 【问题描述】:我正在尝试将一些 Ruby 代码转换为 Python。我在这条线上遇到了麻烦:
Digest::MD5.digest(message).unpack('L*')
我想我应该使用struct
模块和hashlib
一个,但如果我这样做:
struct.unpack('L', hashlib.md5(message).digest())
我收到此错误:
struct.error: unpack requires a bytes object of length 4
我该怎么办? 谢谢你,
魔方
附:输出应该是一个 4 x 32 位整数的列表:
irb(main):039:0> Digest::MD5.digest('Hash').unpack('L*')
=> [631892218, 1967199614, 3683860954, 4130231798]
【问题讨论】:
你试过struct.unpack('LLLL', hashlib.md5(message).digest())
吗?如果这不起作用,请提供您的消息样本。
@ThomasOrozco:哇,它有效!你能解释一下LLLL
的格式吗?谢谢!
LLLL
表示“4 个 32 位整数”。因此,如果您想要 4 个 32 位整数,则使用 LLLL
格式而不是 L
格式,后者只有 1 个 32 位整数。
@ThomasOrozco:太好了!谢谢!
【参考方案1】:
不支持任意长度的解包(*
运算符)。您必须手动指定中继器。
幸运的是,struct 模块确实允许您指定固定长度,并且 hashlib 模块告诉您预期的字节数。通过在L
之前放置一个整数,您可以指定应用该模式的次数。 hashlib
库中的特定散列有一个 .digest_size
attribute,它告诉您特定散列的长度是多少字节。
组合这些:
structspec = '%iL' % (hashlib.hash('md5').digest_size / 4)
struct.unpack(structspec, hashlib.md5(message).digest())
如果您甚至不想在那里硬编码4
,您也可以向struct.calcsize
询问L
unsigned long 的大小:
structspec = '%iL' % (hashlib.hash('md5').digest_size / struct.calcsize('L'))
struct.unpack(structspec, hashlib.md5(message).digest())
事实上,在像我的 Mac 这样的 64 位平台上,L
是 8 个字节,因此如果您要跨不同架构进行部署,后一种计算非常重要。
【讨论】:
【参考方案2】:struct.unpack('L', ...)
只会从参数中解压缩一个 long。您要做的是全部提取,与 Ruby 不同,Python 的解包函数无法解包任意数量的值,而是必须重复格式说明符。
hash = hashlib.md5(message).digest()
struct.unpack('L' * (len(hash) / 4), hash)
这将在字符串允许的范围内重复'L'
并解压缩散列中的所有整数并返回一个包含 len / 4 项的元组。如果您希望将结果作为列表,只需使用list()
将其转换为一个。
【讨论】:
或者,'nL' 也可以使用,n
是一个整数。【参考方案3】:
如果您确定要 4 个 long,格式为 'LLLL':
struct.unpack('LLLL', hashlib.md5(message).digest())
【讨论】:
以上是关于Ruby 解压到 Python的主要内容,如果未能解决你的问题,请参考以下文章