Czy jest tak, że mogę haszować losowy ciąg do 8-cyfrowej liczby bez implementacji żadnych algorytmów samodzielnie?
Czy jest tak, że mogę haszować losowy ciąg do 8-cyfrowej liczby bez implementacji żadnych algorytmów samodzielnie?
Odpowiedzi:
Tak, możesz użyć wbudowanych modułów hashlib lub wbudowanej funkcji skrótu . Następnie odetnij ostatnie osiem cyfr za pomocą operacji modulo lub operacji cięcia łańcuchów na całkowitej postaci hasha:
>>> s = 'she sells sea shells by the sea shore'
>>> # Use hashlib
>>> import hashlib
>>> int(hashlib.sha1(s).hexdigest(), 16) % (10 ** 8)
58097614L
>>> # Use hash()
>>> abs(hash(s)) % (10 ** 8)
82148974
Odpowiedź Raymonda jest świetna dla pythona2 (chociaż nie potrzebujesz abs () ani parens około 10 ** 8). Jednak w przypadku python3 istnieją ważne zastrzeżenia. Najpierw musisz się upewnić, że przekazujesz zakodowany ciąg. W dzisiejszych czasach, w większości przypadków, prawdopodobnie lepiej jest unikać sha-1 i zamiast tego używać czegoś takiego jak sha-256. Zatem podejście hashlib wyglądałoby tak:
>>> import hashlib
>>> s = 'your string'
>>> int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) % 10**8
80262417
Jeśli zamiast tego chcesz użyć funkcji hash (), ważnym zastrzeżeniem jest to, że w przeciwieństwie do Pythona 2.x, w Pythonie 3.x wynik funkcji hash () będzie spójny tylko w ramach procesu, a nie w wywołaniach Pythona. Spójrz tutaj:
$ python -V
Python 2.7.5
$ python -c 'print(hash("foo"))'
-4177197833195190597
$ python -c 'print(hash("foo"))'
-4177197833195190597
$ python3 -V
Python 3.4.2
$ python3 -c 'print(hash("foo"))'
5790391865899772265
$ python3 -c 'print(hash("foo"))'
-8152690834165248934
Oznacza to sugerowane rozwiązanie oparte na hash (), które można skrócić do zaledwie:
hash(s) % 10**8
zwróci tę samą wartość tylko w ramach danego uruchomienia skryptu:
#Python 2:
$ python2 -c 's="your string"; print(hash(s) % 10**8)'
52304543
$ python2 -c 's="your string"; print(hash(s) % 10**8)'
52304543
#Python 3:
$ python3 -c 's="your string"; print(hash(s) % 10**8)'
12954124
$ python3 -c 's="your string"; print(hash(s) % 10**8)'
32065451
Tak więc, w zależności od tego, czy ma to znaczenie w Twojej aplikacji (tak było w mojej), prawdopodobnie będziesz chciał trzymać się podejścia opartego na hashlib.
hashlib.sha256("hello world".encode('utf-8')).hexdigest()[:8]
czarownicy nadal będą miały kolizje
Aby uzupełnić odpowiedź JJC, w pythonie 3.5.3 zachowanie jest poprawne, jeśli używasz hashlib w ten sposób:
$ python3 -c '
import hashlib
hash_object = hashlib.sha256(b"Caroline")
hex_dig = hash_object.hexdigest()
print(hex_dig)
'
739061d73d65dcdeb755aa28da4fea16a02b9c99b4c2735f2ebfa016f3e7fded
$ python3 -c '
import hashlib
hash_object = hashlib.sha256(b"Caroline")
hex_dig = hash_object.hexdigest()
print(hex_dig)
'
739061d73d65dcdeb755aa28da4fea16a02b9c99b4c2735f2ebfa016f3e7fded
$ python3 -V
Python 3.5.3
Dzielę się naszym wdrożeniem nodejs rozwiązania zaimplementowanym przez @Raymond Hettinger.
var crypto = require('crypto');
var s = 'she sells sea shells by the sea shore';
console.log(BigInt('0x' + crypto.createHash('sha1').update(s).digest('hex'))%(10n ** 8n));