Python wykorzystuje losowe ziarno hash, aby uniemożliwić atakującym wykonanie tarowania aplikacji przez wysyłanie kluczy zaprojektowanych do kolizji. Zobacz oryginalne ujawnienie luk w zabezpieczeniach . Zrównując hasz losowym ziarnem (ustawionym raz przy starcie), atakujący nie mogą już przewidzieć, które klucze będą kolidować.
Możesz ustawić stałe ziarno lub wyłączyć tę funkcję, ustawiając PYTHONHASHSEED
zmienną środowiskową ; wartość domyślna to, random
ale możesz ustawić ją na stałą dodatnią liczbę całkowitą, z całkowitym 0
wyłączeniem tej funkcji.
Python w wersjach 2.7 i 3.2 ma tę funkcję domyślnie wyłączoną (użyj -R
przełącznika lub ustaw ją, PYTHONHASHSEED=random
aby ją włączyć); jest on domyślnie włączony w Pythonie 3.3 i nowszych.
Jeśli polegałeś na kolejności kluczy w zestawie Pythona, nie rób tego. Python używa tablicy skrótów do implementacji tych typów, a ich kolejność zależy od historii wstawiania i usuwania, a także od losowego materiału siewnego. Zwróć uwagę, że w Pythonie 3.5 i starszych dotyczy to również słowników.
Zobacz także object.__hash__()
dokumentację metod specjalnych :
Uwaga : Domyślnie __hash__()
wartości obiektów str, bytes i datetime są „salted” z nieprzewidywalną losową wartością. Chociaż pozostają stałe w ramach pojedynczego procesu Pythona, nie można ich przewidzieć między powtarzającymi się wywołaniami Pythona.
Ma to na celu zapewnienie ochrony przed odmową usługi spowodowaną przez starannie dobrane dane wejściowe, które wykorzystują najgorszą wydajność wstawiania dyktowania, złożoność O (n ^ 2). Szczegółowe informacje można znaleźć pod adresem http://www.ocert.org/advisories/ocert-2011-003.html .
Zmiana wartości skrótu wpływa na kolejność iteracji dykt, zestawów i innych mapowań. Python nigdy nie udzielił gwarancji co do takiej kolejności (i zwykle różni się ona między wersjami 32-bitowymi i 64-bitowymi).
Zobacz także PYTHONHASHSEED
.
Jeśli potrzebujesz stabilnej implementacji skrótu, prawdopodobnie zechcesz przyjrzeć się hashlib
modułowi ; to implementuje kryptograficzne funkcje skrótu. Projekt pybloom wykorzystuje to podejście .
Ponieważ offset składa się z przedrostka i sufiksu (odpowiednio wartość początkowa i końcowa wartość XOR), niestety nie można go po prostu zapisać. Z drugiej strony oznacza to, że atakujący nie mogą łatwo określić przesunięcia za pomocą ataków czasowych.
disable
przy ustawianiu na 0? Nie widzę skutecznej różnicy w ustawieniu go na jakikolwiek stary stabilny numer zarodka, chyba że czegoś mi brakuje. Chodzi mi o to, że kiedy używamPYTHONHASHSEED=12345
, otrzymuję ten sam hash dla równych ciągów nawet w sesjach - to samo dzieje się, gdy używamPYTHONHASHSEED=0
- hash dla równych ciągów będzie taki sam we wszystkich sesjach (choć różni się od 12345, ale to oczywiste, w ten sposób nasiona praca).0
ogóle nie ma materiału siewnego, a skróty dla obiektów są równe tym, które zostały wygenerowane w starszej wersji Pythona bez obsługi haszowania.Randomizacja hash jest domyślnie włączona w Pythonie 3 . To jest funkcja bezpieczeństwa:
W poprzednich wersjach od 2.6.8 można było włączyć go w wierszu poleceń za pomocą -R lub opcji środowiska PYTHONHASHSEED .
Możesz go wyłączyć, ustawiając
PYTHONHASHSEED
na zero.źródło
hash () jest funkcją wbudowaną w Pythonie i używa jej do obliczenia wartości skrótu dla obiektu , a nie dla ciągu znaków lub liczby.
Szczegóły możesz zobaczyć na tej stronie: https://docs.python.org/3.3/library/functions.html#hash .
a wartości hash () pochodzą z metody __hash__ obiektu. Doktor mówi, co następuje:
Dlatego masz inną wartość skrótu dla tego samego ciągu w innej konsoli.
To, co wdrażasz, nie jest dobrym sposobem.
Jeśli chcesz obliczyć wartość skrótu ciągu, po prostu użyj hashlib
hash () ma na celu uzyskanie wartości skrótu obiektu, a nie mieszania.
źródło
hash()
doskonale sprawdza się w przypadku wartości łańcuchowych lub liczbowych. Mylisz to z__hash__
metodą niestandardową, używaną przez program whash()
celu zapewnienia niestandardowej implementacji wartości skrótu.