Existe alguma maneira que eu possa hash uma string aleatória em um número de 8 dígitos sem implementar nenhum algoritmo sozinho?
Existe alguma maneira que eu possa hash uma string aleatória em um número de 8 dígitos sem implementar nenhum algoritmo sozinho?
Respostas:
Sim, você pode usar os módulos hashlib embutidos ou a função hash embutida. Em seguida, corte os últimos oito dígitos usando operações de módulo ou operações de corte de string na forma inteira do hash:
>>> 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
A resposta de Raymond é ótima para python2 (embora você não precise do abs () nem dos parênteses em torno de 10 ** 8). No entanto, para python3, existem ressalvas importantes. Primeiro, você precisa se certificar de que está passando uma string codificada. Hoje em dia, na maioria das circunstâncias, provavelmente também é melhor fugir do sha-1 e usar algo como o sha-256. Portanto, a abordagem hashlib seria:
>>> import hashlib
>>> s = 'your string'
>>> int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) % 10**8
80262417
Se você quiser usar a função hash (), a ressalva importante é que, ao contrário do Python 2.x, no Python 3.x, o resultado de hash () só será consistente dentro de um processo, não entre invocações de python. Veja aqui:
$ 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
Isso significa que a solução baseada em hash () sugerida, que pode ser encurtada para apenas:
hash(s) % 10**8
retornará apenas o mesmo valor em uma determinada execução de script:
#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
Portanto, dependendo se isso é importante no seu aplicativo (foi no meu), você provavelmente vai querer manter a abordagem baseada em hashlib.
hashlib.sha256("hello world".encode('utf-8')).hexdigest()[:8]
ainda assim haverá colisões
Apenas para completar a resposta JJC, no python 3.5.3 o comportamento está correto se você usar hashlib desta forma:
$ 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
Estou compartilhando nossa implementação nodejs da solução implementada por @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));