Python 如何将字符串散列成8位数字?

Python 如何将字符串散列成8位数字?,python,arrays,algorithm,random,hash,Python,Arrays,Algorithm,Random,Hash,我是否可以将一个随机字符串散列成8位数字,而不用自己实现任何算法?是的,您可以使用内置模块或内置函数。然后,在散列的整数形式上使用模运算或字符串切片操作切掉最后八位数字: >>> s = 'she sells sea shells by the sea shore' >>> # Use hashlib >>> import hashlib >>> int(hashlib.sha1(s.encode("utf-8&

我是否可以将一个随机字符串散列成8位数字,而不用自己实现任何算法?

是的,您可以使用内置模块或内置函数。然后,在散列的整数形式上使用模运算或字符串切片操作切掉最后八位数字:

>>> s = 'she sells sea shells by the sea shore'

>>> # Use hashlib
>>> import hashlib
>>> int(hashlib.sha1(s.encode("utf-8")).hexdigest(), 16) % (10 ** 8)
58097614L

>>> # Use hash()
>>> abs(hash(s)) % (10 ** 8)
82148974

Raymond的答案对于python2非常有用(不过,你不需要10**8左右的abs()或paren)。然而,对于python3,有一些重要的警告。首先,您需要确保传递的是编码字符串。现在,在大多数情况下,最好还是避开sha-1,改用类似sha-256的东西。因此,hashlib方法是:

>>> import hashlib
>>> s = 'your string'
>>> int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) % 10**8
80262417
如果您想改用hash()函数,重要的警告是,与Python2.x不同,Python3.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()的解决方案可以缩短为:

散列%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的方法。

仅为了完成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

我正在分享由@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));

哈希(“您的字符串”)%1000000008位似乎很小,如果您有大量记录,可能会导致哈希冲突。使用hashlib,因为hash还有另一个用途!任何有限数量的数字都会导致足够多的散列项发生冲突,这就是为什么不应将它们视为唯一键的原因-这往往会变成生日问题。我选择“CityHash”将字符串散列为19位长的整数(64位整数),希望这将导致比下面雷蒙德的建议更少的潜在碰撞。公共服务公告…此技术实际上不会为字符串生成唯一的哈希值;它计算一个散列,然后咀嚼一个不保证唯一值的公共服务公告…除了在有限的输入值集上进行完美散列的特殊情况外,散列函数不应该生成保证唯一值。你读过OP的问题了吗?他(或她)想要(或需要)8位小数。此外,散列表的工作方式是散列到一个小的搜索空间(稀疏表)。你似乎不知道want散列函数是常用的,也不关心被问到的实际问题。我只是观察到,在与SHA-1相同的输入空间中,你的答案在天文上更有可能产生碰撞。这个问题至少隐含着某种程度的唯一性,但您的答案是一个哈希函数,其精神与只为每个输入返回12345678的哈希函数相同。我能够用这种方法在实验上产生一个只有1000个输入的碰撞。为了保持与SHA-1相同的碰撞概率,必须将未截断的SHA-1映射为8位整数。我认为这是值得仔细考虑的,散列不能保证在不同平台和运行时给出相同的结果。应该注意的是,这个答案有一个非常重要的警告,因为Python 3.3,为了防止Python3.3及以上版本出现焦油污染,请在启动时使用随机哈希种子。如果数字不是您的主要要求,您也可以使用
hashlib.sha256(“hello world”.encode('utf-8')).hexdigest()[:8]
witch仍然会有冲突,他们应该将其放在框中!您正在分享一个关于python的问题中的nodejs解决方案?是的,当我们构建系统时-后端使用python处理此问题,而前端使用node.js。需要确保两者无缝工作。