Python usa una semilla de hash aleatoria para evitar que los atacantes pongan alquitrán en su aplicación enviándole claves diseñadas para colisionar. Ver la divulgación de vulnerabilidad original . Al compensar el hash con una semilla aleatoria (establecida una vez al inicio), los atacantes ya no pueden predecir qué claves colisionarán.
Puede establecer una semilla fija o deshabilitar la función configurando la PYTHONHASHSEED
variable de entorno ; el valor predeterminado es, random
pero puede establecerlo en un valor entero positivo fijo, con0
deshabilitando la función por completo.
Las versiones 2.7 y 3.2 de Python tienen la función deshabilitada de forma predeterminada (use el -R
interruptor o configurePYTHONHASHSEED=random
para habilitarlo); está habilitado de forma predeterminada en Python 3.3 y versiones posteriores.
Si confiaba en el orden de las claves en un conjunto de Python, entonces no lo haga. Python usa una tabla hash para implementar estos tipos y su orden depende del historial de inserción y eliminación , así como de la semilla hash aleatoria. Tenga en cuenta que en Python 3.5 y versiones anteriores, esto también se aplica a los diccionarios.
Consulte también la object.__hash__()
documentación del método especial :
Nota : De forma predeterminada, los __hash__()
valores de str, bytes y objetos de fecha y hora son "salados" con un valor aleatorio impredecible. Aunque permanecen constantes dentro de un proceso de Python individual, no son predecibles entre invocaciones repetidas de Python.
Esto está destinado a proporcionar protección contra una denegación de servicio causada por entradas cuidadosamente seleccionadas que explotan el peor rendimiento de una inserción de dict, complejidad O (n ^ 2). Ver http://www.ocert.org/advisories/ocert-2011-003.html para obtener más detalles.
El cambio de los valores hash afecta el orden de iteración de los dictados, conjuntos y otras asignaciones. Python nunca ha ofrecido garantías sobre este pedido (y normalmente varía entre compilaciones de 32 y 64 bits).
Vea también PYTHONHASHSEED
.
Si necesita una implementación de hash estable, probablemente desee ver el hashlib
módulo ; esto implementa funciones hash criptográficas. El proyecto pybloom utiliza este enfoque .
Dado que el desplazamiento consta de un prefijo y un sufijo (valor inicial y valor final XORed, respectivamente), no puede simplemente almacenar el desplazamiento, por desgracia. En el lado positivo, esto significa que los atacantes tampoco pueden determinar fácilmente la compensación con los ataques de tiempo.
disable
cuando lo establece en 0? No veo la diferencia efectiva para establecerlo en cualquier número de semilla estable antiguo, a menos que me falte algo. Lo que quiero decir es que cuando usoPYTHONHASHSEED=12345
, obtengo el mismo hash para cadenas iguales incluso en todas las sesiones, lo mismo sucede cuando lo usoPYTHONHASHSEED=0
, el hash para cadenas iguales será el mismo en todas las sesiones (aunque diferente a 12345, pero eso es obvio, así es como las semillas trabajo).0
ninguna semilla y los hash de los objetos son iguales a los generados en una versión anterior de Python sin ningún soporte de hashseed.La aleatorización de hash está activada de forma predeterminada en Python 3 . Esta es una característica de seguridad:
En versiones anteriores de 2.6.8, podía activarlo en la línea de comandos con -R, o la opción de entorno PYTHONHASHSEED .
Puede apagarlo poniéndolo
PYTHONHASHSEED
a cero.fuente
hash () es una función incorporada de Python y se usa para calcular un valor hash para el objeto , no para la cadena o num.
Puede ver el detalle en esta página: https://docs.python.org/3.3/library/functions.html#hash .
y los valores hash () provienen del método __hash__ del objeto. El doctor dice lo siguiente:
Es por eso que tiene un valor hash diferente para la misma cadena en una consola diferente.
Lo que implementa no es una buena manera.
Cuando desee calcular un valor hash de cadena, simplemente use hashlib
hash () tiene como objetivo obtener un valor hash de objeto, no una agitación.
fuente
hash()
es perfectamente válido para cadenas o valores numéricos. Está confundiendo esto con el__hash__
método personalizado, utilizado porhash()
para proporcionar una implementación personalizada del valor hash.