2011-04-07 10 views
12

Necesito calcular un hash que debe ser estable en todas las arquitecturas. ¿Es estable el hash() de python?¿El método de hash incorporado de Python2.6 es estable en todas las arquitecturas?

Para ser más específicos, el siguiente ejemplo muestra almohadilla() calcular el mismo valor en dos diferentes hosts/arquitecturas:

# on OSX based laptop 
>>> hash((1,2,3,4)) 
485696759010151909 
# on x86_64 Linux host 
>>> hash((1,2,3,4)) 
485696759010151909 

Lo anterior es cierto para al menos los insumos, pero mi pregunta es para el caso general

Respuesta

11

Si necesita un hash bien definido, puede utilizar uno de hashlib.

+0

Para esto, necesitas un "str" ​​estable, que creo que es cierto. – kennytm

+0

@KennyTM: Sí, los resultados de 'str()' deberían ser los mismos en todas las plataformas e implementaciones. – nmichaels

+0

Eso es lo que estaba pensando, igual de sencillo también. Gracias – daniel

5

x86_64 
>>> print hash("a") 
12416037344 

i386 
>>> print hash("a") 
-468864544 

Si necesita un hash estable, crear un resumen de sus datos utilizando algo así como SHA1, que se pueden encontrar en hashlib

5

Nº en el brazo con el pitón 2.6:

>>> hash((1,2,3,4)) 

89902565

6

La función hash() no es lo que desea; encontrar una manera confiable de serializar el objeto (por ejemplo, str() o repr()) y ejecutarlo a través de hashlib.md5() probablemente sería mucho más preferible.

En detalle - hash() está diseñado para devolver un entero que identifica de manera única un objeto solo dentro de su vida útil. Una vez que el programa se ejecuta nuevamente, la construcción de un nuevo objeto de hecho puede tener un hash diferente. Destruir un objeto significa que hay una posibilidad de que otro objeto tenga ese hash en el futuro. Consulte la definición de Python de hashable para obtener más información.

Detrás de escena, la mayoría de los objetos de pitón definidos por el usuario se vuelven a id() para proporcionar su valor hash. Si bien se supone que no debe hacer uso de esto, id(obj) y por lo tanto hash(obj) generalmente se implementa (por ejemplo, en CPython) como la dirección de memoria del objeto Python subyacente. Por lo tanto, puedes ver por qué no se puede confiar en nada.

El comportamiento que ve actualmente solo es confiable para ciertos objetos incorporados de python, y no muy lejos. hash({}) por ejemplo, no es posible.


En cuanto hashlib.md5(str(obj)) o equivalente - que necesita para asegurarse de str(obj) es fiable la misma. En particular, si tiene un diccionario en ejecución dentro de esa cadena, es posible que no enumere sus claves en el mismo orden. También puede haber diferencias sutiles entre las versiones de Python ... Definitivamente recomendaría pruebas de unidad para cualquier implementación en la que confíe.

+0

El segundo párrafo realmente podría usar una referencia. ¿Hay una documentación oficial de esa información? – phihag

+0

@phihag Casi todos los párrafos 2º y 3º son solo una reexpresión de la información en la documentación oficial 'hashable' y' id() 'vinculada dentro de los párrafos; aunque los documentos oficiales podrían deletrear las cosas un poco mejor. –

+0

No identifica un objeto de manera única. Solo proporciona una asignación en el dominio int con una buena distribución. Las colisiones son inevitables y cuidadas. – sleeplessnerd

Cuestiones relacionadas