Pregunta

Tengo (3) md5sums que necesito combinar en un solo hash.El nuevo hash debe ser de 32 caracteres, pero distingue entre mayúsculas y minúsculas y puede ser cualquier letra o número.¿Cuál es la mejor manera de hacer esto en Python?

¿Fue útil?

Solución

Comencionaría combinando los hashes MD5 en un solo hash.Puede usar SHA256 ya que contendrá más bytes al final:

>>> import hashlib
>>> combined = hashlib.sha256()
>>> combined.update(hashlib.md5('test1').digest())
>>> combined.update(hashlib.md5('test2').digest())
>>> combined.update(hashlib.md5('test3').digest())

Luego, puede usar BASE64 para codificarlo usando letras, números y algunos símbolos adicionales:

>>> import base64
>>> base64.b64encode(combined.digest())
'PeFC3irNFx8fuzwjAz+fE/up9cz6xujs2Z06IH2GdUM='

Si desea solo 32 caracteres, rebanando de los últimos bits:

>>> base64.b64encode(combined.digest())[:32]
'PeFC3irNFx8fuzwjAz+fE/up9cz6xujs'

Esto puede contener + y /, además de letras y números como su OP sugiere.Si desea reemplazarlos, puede usar el segundo parámetro a B64Encodo:

>>> base64.b64encode(combined.digest(), altchars="AA")[:32]
'PeFC3irNFx8fuzwjAzAfEAup9cz6xujs'

Otros consejos

La forma más fácil sería combinar las 3 sumas en una sola cadena de 96 caracteres y ejecutar un hash MD5 en ese.

>>> from hashlib import md5
>>> import base64
>>> hashes = [md5(str(i)).hexdigest() for i in range(3)]
>>> hashes
['cfcd208495d565ef66e7dff9f98764da', 'c4ca4238a0b923820dcc509a6f75849b', 'c81e728d9d4c2f636f067f89cc14862c']
>>> base64.b64encode(md5(''.join(hashes)).hexdigest())[:32]
'YTg2N2M3N2U0Mzg2YjY1YWY4NzYzOWZh'

Solo por otra forma, usando "personajes" para significar cualquier punto de codigo de Unicode, aquí está lo que acumulé, incluido mi Bumbey Round:

>>> hashes = ['96a77af1cce6dc64ed5d4c381bb7f143',
...  '11b13de4792e0407aae4a40fd6e4e2d4',
...  'eec7e31c5e2890adaf0d999835c976fc',
... ]
>>> int(''.join(hashes), 16)
23187806638669244987192443940605368881272088351426889142645412473142674081465702767335075936780031545889279263209212L
>>> n=_
>>> (48 * 8) / 32  # calculating bits per character
12
>>> 1 << 12
4096
>>> chars = []
>>> for i in range(32):
...  chars.append(unichr(n % 4096))
...  n /= 4096
... 
>>> chars
[u'\u06fc', u'\u0c97', u'\u0835', u'\u0999', u'\u0f0d', u'\u0ada', u'\u0890', u'\u05e2', u'\u031c', u'\u0c7e', u'\u04ee', u'\u0e2d', u'\u06e4', u'\xfd', u'\u04a4', u'\u0aae', u'\u0407', u'\u02e0', u'\u0479', u'\u03de', u'\u01b1', u'\u0431', u'\u07f1', u'\u01bb', u'\u0c38', u'\u05d4', u'\u04ed', u'\u0dc6', u'\u0ce6', u'\u0f1c', u'\u077a', u'\u096a']
>>> ''.join(chars)
u'\u06fc\u0c97\u0835\u0999\u0f0d\u0ada\u0890\u05e2\u031c\u0c7e\u04ee\u0e2d\u06e4\xfd\u04a4\u0aae\u0407\u02e0\u0479\u03de\u01b1\u0431\u07f1\u01bb\u0c38\u05d4\u04ed\u0dc6\u0ce6\u0f1c\u077a\u096a'
>>> print _
ۼಗ࠵ঙ།૚࢐ע̜౾ӮอۤýҤમЇˠѹϞƱб߱ƻసהӭෆ೦༜ݺ४

Probablemente habría tenido que usar 13 bits por carácter para evitar cualquier puntuación, pero no quería invertir el tiempo desde que no le importaba la reversibilidad de todos modos.

[más tarde] No, no tenía que:

>>> hashes = ['96a77af1cce6dc64ed5d4c381bb7f143',
...  '11b13de4792e0407aae4a40fd6e4e2d4',
...  'eec7e31c5e2890adaf0d999835c976fc',
... ]
>>> charlist = filter(lambda c: c.isalnum(), map(unichr, range(8000)))
>>> len(charlist)
5032
>>> n = int(''.join(hashes), 16)
>>> n
23187806638669244987192443940605368881272088351426889142645412473142674081465702767335075936780031545889279263209212L
>>> chars = []
>>> for i in range(32):
...  chars.append(charlist[n % 4096])
...  n /= 4096
... 
>>> chars
[u'\u0b67', u'\u1448', u'\u0dc5', u'\u10f4', u'\u16cf', u'\u124a', u'\u0ea7', u'\u0931', u'\u0442', u'\u142f', u'\u06c7', u'\u15de', u'\u0b26', u'\u0178', u'\u067d', u'\u121d', u'\u0542', u'\u0406', u'\u0638', u'\u050c', u'\u022c', u'\u0575', u'\u0d6b', u'\u0236', u'\u13dd', u'\u0923', u'\u06c6', u'\u1577', u'\u1497', u'\u16de', u'\u0c87', u'\u10bb']
>>> print ''.join(chars)
୧ᑈළჴᛏቊວऱтᐯۇᗞଦŸٽምՂІظԌȬյ൫ȶᏝणۆᕷᒗᛞಇႻ

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top