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的主要内容,如果未能解决你的问题,请参考以下文章

Ruby - 解压不规则的二进制字符串

python 3.2版本 解压rar/zip到指定目录

Ruby收获

Python编程:从入门到实践.pdf 解压密码?

如何在java中解压二进制文件?

python 文件解压