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.
disable
ao definir como 0? Não vejo diferença efetiva em configurá-lo para qualquer número de semente estável antigo, a menos que esteja faltando alguma coisa. O que quero dizer é que, quando eu usoPYTHONHASHSEED=12345
, obtenho o mesmo hash para strings iguais, mesmo nas sessões - o mesmo acontece quando eu usoPYTHONHASHSEED=0
- o hash para strings iguais será o mesmo entre as sessões (embora seja diferente de 12345, mas isso é óbvio, é assim que as sementes trabalhos).0
não há nenhuma semente e os hashes para objetos são iguais aos gerados em uma versão mais antiga do Python sem qualquer suporte para hashseed.A randomização de hash é ativada por padrão no Python 3 . Este é um recurso de segurança:
Em versões anteriores de 2.6.8, você poderia ativá- lo na linha de comando com -R ou a opção de ambiente PYTHONHASHSEED .
Você pode desligá-lo definindo
PYTHONHASHSEED
como zero.fonte
hash () é uma função integrada do Python e usa-a para calcular um valor de hash para o objeto , não para string ou num.
Você pode ver os detalhes nesta página: https://docs.python.org/3.3/library/functions.html#hash .
e os valores hash () vêm do método __hash__ do objeto. O doc diz o seguinte:
É por isso que você tem um valor hash diferente para a mesma string em um console diferente.
O que você implementa não é uma boa maneira.
Quando você quiser calcular um valor de hash de string, basta usar hashlib
hash () tem como objetivo obter um valor de hash de objeto, não uma agitação.
fonte
hash()
é perfeitamente válido para string ou valores numéricos. Você está confundindo isso com o__hash__
método personalizado, usado porhash()
para fornecer uma implementação personalizada do valor hash.