问题:如何将字符串散列为8位数字?
无论如何,我可以将随机字符串散列为8位数字而无需自己实现任何算法吗?
回答 0
是的,您可以使用内置的hashlib模块或内置的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
回答 1
Raymond的答案对于python2非常有用(尽管您不需要abs()或10 ** 8附近的括号)。但是,对于python3,有一些重要的警告。首先,您需要确保传递编码的字符串。如今,在大多数情况下,最好避开sha-1并改用sha-256之类的东西。因此,hashlib方法将是:
>>> import hashlib
>>> s = 'your string'
>>> int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) % 10**8
80262417
如果要改用hash()函数,则需要注意的重要一点是,与Python 2.x不同,在Python 3.x中,hash()的结果将仅在进程内保持一致,而在整个python调用之间均保持一致。看这里:
$ 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
这意味着建议使用基于hash()的解决方案,可以将其简化为:
hash(s) % 10**8
将仅在给定的脚本运行中返回相同的值:
#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
因此,取决于这是否在您的应用程序中很重要(它在我的应用程序中确实如此),您可能希望坚持使用基于hashlib的方法。
回答 2
只是为了完成JJC答案,在python 3.5.3中,如果您通过以下方式使用hashlib,则行为是正确的:
$ 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
回答 3
我将分享由@Raymond Hettinger实施的解决方案的nodejs实施。
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));