0

私はPythonでmd5チェックサムを持っています。のようにs = '14966ba801aed57c2771c7487c7b194a'

私が欲しいのは、ランダムなmd5チェックサムのエントロピーを失うことなく、それを短くして「a-zA-Z0-9_.-」の形式の文字列にすることです。

出力は発音可能でなければならないので、私はただそれをすることはできませんbinascii.unhexlify(s)。またbase64.encodestring(s)、エントロピーが失われるため、それを実行してカットすることもできません。

非常識な数(256)の16進ペア(00-> FF)を別の文字にマッピングせずにこれを解決する方法についてのアイデアはありますか?

これが必要な理由は、電話でmd5チェックサム全体を言うことができるようにするためですが、アルファベット全体+数字+いくつかの特殊文字を使用します。

4

3 に答える 3

4

I'm going to play fast and loose with your requirements a little and take a shot at something which I think might help you.

Reading over what you've written, the requirement that stands out to me is a way to read a message digest over the phone.

To that end, you might want to look at Bubble Babble. Bubble Babble is designed to encode a digest (or other things) into a pronounceable string:

ASCII Input       Encoding
------------------------------------------------------------------
`' (empty string) `xexax'
`1234567890'      `xesef-disof-gytuf-katof-movif-baxux'
`Pineapple'       `xigak-nyryk-humil-bosek-sonax'

Here's a Python implementation: http://code.activestate.com/recipes/299133-bubblebabble/

于 2012-04-30T11:15:04.700 に答える
2

Since you want the "number" (yes, a md5 hash is nothing but a base16 number, we can of course convert that to base-something to shorten the string) to be pronouncable over the phone, I suggest avoiding mixed upper- / lowercase. And when we only allow [0-9A-Z], we can simply use the builtin int() with Base36 for decoding.

See:

>>> 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'

You could of course use a longer alphabet to shorten the resulting string, but then you'd have to write your own decode() function. Should not be too hard, though.

于 2012-04-30T12:35:30.870 に答える
0
于 2012-04-30T11:06:04.287 に答える