Python usa uma semente de hash aleatória para evitar que invasores ataquem seu aplicativo enviando chaves projetadas para colidir. Veja a divulgação original da vulnerabilidade . Ao compensar o hash com uma semente aleatória (definida uma vez na inicialização), os invasores não podem mais prever quais chaves entrarão em conflito.
Você pode definir uma semente fixa ou desativar o recurso definindo a PYTHONHASHSEED
variável de ambiente ; o padrão é, random
mas você pode defini-lo como um valor inteiro positivo fixo, com a 0
desativação do recurso por completo.
As versões 2.7 e 3.2 do Python têm o recurso desabilitado por padrão (use a -R
opção ou defina PYTHONHASHSEED=random
para habilitá-lo); ele é habilitado por padrão no Python 3.3 e superior.
Se você estava contando com a ordem das chaves em um conjunto Python, não o faça. Python usa uma tabela de hash para implementar esses tipos e sua ordem depende do histórico de inserção e exclusão , bem como da semente de hash aleatória. Observe que no Python 3.5 e anteriores, isso também se aplica aos dicionários.
Veja também a object.__hash__()
documentação do método especial :
Nota : Por padrão, os __hash__()
valores dos objetos str, bytes e datetime são “salgados” com um valor aleatório imprevisível. Embora permaneçam constantes em um processo individual do Python, eles não são previsíveis entre invocações repetidas do Python.
Isso se destina a fornecer proteção contra uma negação de serviço causada por entradas cuidadosamente escolhidas que exploram o desempenho de pior caso de uma inserção de dicionário, complexidade O (n ^ 2). Consulte http://www.ocert.org/advisories/ocert-2011-003.html para obter detalhes.
Alterar os valores de hash afeta a ordem de iteração de dictos, conjuntos e outros mapeamentos. Python nunca deu garantias sobre essa ordem (e normalmente varia entre compilações de 32 e 64 bits).
Veja também PYTHONHASHSEED
.
Se você precisar de uma implementação de hash estável, provavelmente desejará examinar o hashlib
módulo ; isso implementa funções de hash criptográficas. O projeto pybloom usa essa abordagem .
Como o deslocamento consiste em um prefixo e um sufixo (valor inicial e valor final XORed, respectivamente), você não pode simplesmente armazenar o deslocamento, infelizmente. No lado positivo, isso significa que os invasores também não podem determinar facilmente o deslocamento com ataques temporizados.