0

我在 python 中有一个 md5 校验和;喜欢s = '14966ba801aed57c2771c7487c7b194a'

我想要的是缩短它并使其成为'a-zA-Z0-9_.-'形式的字符串,而不会丢失我的随机md5校验和的熵。

输出必须是可发音的,所以我不能这样做binascii.unhexlify(s)。我也不能做base64.encodestring(s)和削减它,因为那样我会失去熵。

关于如何在不将十六进制对(00->FF)的疯狂数字(256)映射到不同字母的情况下解决此问题的任何想法?

我想要这个的原因是能够通过电话说出整个 md5 校验和,但使用整个字母+数字+一些特殊字符。

4

3 回答 3

4

我将根据您的要求快速而松散地玩一下,并尝试一些我认为可能对您有帮助的东西。

阅读您所写的内容,对我来说突出的要求是通过电话阅读消息摘要的一种方式。

为此,您可能需要查看Bubble Babble。Bubble Babble 旨在将摘要(或其他内容)编码为可发音的字符串:

ASCII 输入编码
-------------------------------------------------- ----------------
`' (空字符串) `xexax'
`1234567890' `xesef-disof-gytuf-katof-movif-baxux'
`菠萝' `xigak-nyryk-humil-bosek-sonax'

这是一个 Python 实现:http ://code.activestate.com/recipes/299133-bubblebabble/

于 2012-04-30T11:15:04.700 回答
2

由于您希望“数字”(是的,md5 哈希只不过是一个 base16 数字,我们当然可以将其转换为 base-something 以缩短字符串)在电话中可以发音,因此我建议避免混合大写/小写. 而当我们只允许 [0-9A-Z] 时,我们可以简单地使用带有 Base36 的内置 int() 进行解码。

看:

>>> def encode(num):
        import string
        ALPHABET = string.digits + string.ascii_uppercase
        tmp = []
        while num:
            num, rem = divmod(num, len(ALPHABET))
            tmp.append(ALPHABET[rem])
        return ''.join(reversed(tmp))

>>> import hashlib
>>> the_hash = hashlib.md5('test').hexdigest()
>>> decimal_representation = int(the_hash, 16)
>>> encoded = encode(decimal_representation)
>>> the_hash
'098f6bcd4621d373cade4e832627b4f6'
>>> decimal_representation
12707736894140473154801792860916528374L
>>> encoded
'KDISMNX5MOYU6Q6PZT8TQDPY'
>>> decimal_representation == int(encoded, 36)
True
>>> hex(int(encoded, 36))
'0x98f6bcd4621d373cade4e832627b4f6L'

您当然可以使用更长的字母来缩短生成的字符串,但是您必须编写自己的 decode() 函数。不过,应该不会太难。

于 2012-04-30T12:35:30.870 回答
0
于 2012-04-30T11:06:04.287 回答