Python utilise une graine de hachage aléatoire pour empêcher les attaquants de piquer votre application en vous envoyant des clés conçues pour entrer en collision. Voir la divulgation de vulnérabilité d'origine . En compensant le hachage avec une graine aléatoire (définie une fois au démarrage), les attaquants ne peuvent plus prédire quelles clés entreront en collision.
Vous pouvez définir une valeur de départ fixe ou désactiver la fonctionnalité en définissant la PYTHONHASHSEED
variable d'environnement ; la valeur par défaut est, random
mais vous pouvez la définir sur une valeur entière positive fixe, en 0
désactivant complètement la fonctionnalité.
Les versions 2.7 et 3.2 de Python ont la fonctionnalité désactivée par défaut (utilisez le -R
commutateur ou défini PYTHONHASHSEED=random
pour l'activer); il est activé par défaut dans Python 3.3 et plus.
Si vous vous fiez à l'ordre des clés dans un ensemble Python, alors ne le faites pas. Python utilise une table de hachage pour implémenter ces types et leur ordre dépend de l'historique d'insertion et de suppression ainsi que de la graine de hachage aléatoire. Notez que dans Python 3.5 et versions antérieures, cela s'applique également aux dictionnaires.
Consultez également la object.__hash__()
documentation de la méthode spéciale :
Remarque : Par défaut, les __hash__()
valeurs des objets str, bytes et datetime sont «salées» avec une valeur aléatoire imprévisible. Bien qu'ils restent constants au sein d'un processus Python individuel, ils ne sont pas prévisibles entre des invocations répétées de Python.
Ceci est destiné à fournir une protection contre un déni de service causé par des entrées soigneusement choisies qui exploitent les pires performances d'une insertion de dict, complexité O (n ^ 2). Voir http://www.ocert.org/advisories/ocert-2011-003.html pour plus de détails.
La modification des valeurs de hachage affecte l'ordre d'itération des dictionnaires, ensembles et autres mappages. Python n'a jamais donné de garanties sur cet ordre (et il varie généralement entre les versions 32 bits et 64 bits).
Voir aussi PYTHONHASHSEED
.
Si vous avez besoin d'une implémentation de hachage stable, vous voudrez probablement regarder le hashlib
module ; cela implémente des fonctions de hachage cryptographiques. Le projet pybloom utilise cette approche .
Étant donné que le décalage se compose d'un préfixe et d'un suffixe (valeur de départ et valeur XOR finale, respectivement), vous ne pouvez malheureusement pas simplement stocker le décalage. Du côté positif, cela signifie que les attaquants ne peuvent pas non plus facilement déterminer le décalage avec les attaques de synchronisation.
disable
lors de sa mise à 0? Je ne vois pas la différence effective en le définissant sur un ancien numéro de graine stable, à moins que quelque chose me manque. Ce que je veux dire, c'est que lorsque j'utilise,PYTHONHASHSEED=12345
j'obtiens le même hachage pour des chaînes égales, même entre les sessions - la même chose se produit lorsque j'utilisePYTHONHASHSEED=0
- le hachage pour des chaînes égales sera le même d'une session à l'autre (bien que différent de 12345, mais c'est évident, c'est ainsi que les graines travail).0
il n'y a pas du tout de graine et les hachages pour les objets sont égaux à ceux générés dans une ancienne version de Python sans aucun support de hachage.La randomisation de hachage est activée par défaut dans Python 3 . Ceci est une fonction de sécurité:
Dans les versions précédentes de la 2.6.8, vous pouviez l'activer sur la ligne de commande avec -R ou l' option d'environnement PYTHONHASHSEED .
Vous pouvez le désactiver en le mettant
PYTHONHASHSEED
à zéro.la source
hash () est une fonction intégrée de Python et l'utilise pour calculer une valeur de hachage pour un objet , pas pour une chaîne ou un nombre.
Vous pouvez voir le détail dans cette page: https://docs.python.org/3.3/library/functions.html#hash .
et les valeurs de hash () proviennent de la méthode __hash__ de l'objet. Le doc dit ce qui suit:
C'est pourquoi vous avez une valeur de hachage différente pour la même chaîne dans une console différente.
Ce que vous implémentez n'est pas un bon moyen.
Lorsque vous souhaitez calculer une valeur de hachage de chaîne, utilisez simplement hashlib
hash () vise à obtenir une valeur de hachage d'objet, pas une agitation.
la source
hash()
est parfaitement valable pour les valeurs de chaîne ou numériques. Vous confondez cela avec la__hash__
méthode personnalisée, utilisée parhash()
pour fournir une implémentation personnalisée de la valeur de hachage.