我需要的是散列一个字符串。它不一定是安全的,因为它只是文本文件中的一个隐藏短语(它不必是人眼可识别的)。
它不应该只是一个随机字符串,因为当用户键入字符串时,我想对其进行散列并将其与已经散列的字符串(来自文本文件)进行比较。
什么是最好的?可以用内置类来完成吗?
我需要的是散列一个字符串。它不一定是安全的,因为它只是文本文件中的一个隐藏短语(它不必是人眼可识别的)。
它不应该只是一个随机字符串,因为当用户键入字符串时,我想对其进行散列并将其与已经散列的字符串(来自文本文件)进行比较。
什么是最好的?可以用内置类来完成吗?
首先,让我说你不能保证独特的结果。如果您想要宇宙中所有字符串的唯一结果,最好存储字符串本身(或压缩版本)。
稍后会详细介绍。让我们先获取一些哈希值。
您可以通过几个步骤使用任何主要的加密散列来散列字符串:
>>> import hashlib
>>> sha = hashlib.sha1("I am a cat")
>>> sha.hexdigest()
'576f38148ae68c924070538b45a8ef0f73ed8710'
就内置而言,您可以在 SHA1、SHA224、SHA256、SHA384、SHA512 和 MD5 之间进行选择。
哈希函数通过获取可变长度的数据并将其转换为固定长度的数据来工作。
对于内置的每个 SHA 算法,固定长度hashlib
是名称中指定的位数(sha1 除外,它是 160 位)。如果您想更好地确定两个字符串不会最终出现在同一个桶中(相同的哈希值),请选择具有更大摘要(固定长度)的哈希。
按排序顺序,这些是您必须使用的摘要大小:
Algorithm Digest Size (in bits)
md5 128
sha1 160
sha224 224
sha256 256
sha384 384
sha512 512
如果您的哈希函数物有所值,那么摘要越大,发生冲突的可能性就越小。
hash()
?内置hash()
函数返回整数,这也可以很容易地用于您概述的目的。不过也有问题。
>>> hash('moo')
6387157653034356308
如果你的程序要在不同的系统上运行,你不能确定它hash
会返回相同的东西。事实上,我正在使用 64 位 Python 的 64 位机器上运行。这些值将与 32 位 Python 大不相同。
正如@gnibbler 所指出的,对于 Python 3.3+,hash()
在运行之间是随机的。它适用于单次运行,但几乎肯定不会跨程序运行(从您提到的文本文件中提取)。
为什么会hash()
这样建造?好吧,内置哈希是出于一个特定的原因。哈希表/字典/在内存中查找表。不是为了加密使用,而是为了在运行时进行廉价查找。
不使用hash()
,使用hashlib
。
您可以简单地使用 base64 模块来实现您的目标:
>>> import base64
>>> a = 'helloworld'
>>> encoded_str = base64.encodestring(a)
>>> encoded_str
'aGVsbG93b3JsZA=='
>>> base64.decodestring(encoded_str)
'helloworld'
>>>
当然你也可以使用 hashlib 模块,它更安全,因为散列字符串不能(或非常非常难)被解码,但是对于你的问题 base64 就足够了——“它并不一定是安全的”
请注意,Python 的字符串哈希不是“定义的”——它可以而且确实会因版本和实现而异。因此存储 Python 字符串哈希会产生困难。CPython 的字符串散列也没有试图变得“晦涩”。
一种标准方法是使用为此类事物设计的哈希函数。像这样:
>>> import hashlib
>>> encoded = hashlib.sha1("abcdef") # "abcdef" is the password
>>> encoded.hexdigest()
'1f8ac10f23c5b5bc1167bda84b833e5c057a77d2'
那一长串十六进制数字是“哈希”。SHA-1 是一个“强”的散列函数。如果你找到两个哈希值相同的字符串,你就会出名 ;-) 并且给定相同的输入,它将在所有平台上的所有 Python 版本和实现中返回相同的“hexdigest”。
只需使用hash()
内置函数,例如:
s = 'a string'
hash(s)
=> -8411828025894108412