在Python中散列(隐藏)字符串

时间:2013-10-25 03:06:53

标签: python string encryption hash

我需要的是散列字符串。它不必是安全的,因为它只是文本文件中的隐藏短语(它不一定是人眼可识别的)。

它不应该只是一个随机字符串,因为当用户键入字符串时我想将其哈希并将其与已经散列的字符串(来自文本文件)进行比较。

为此目的最好的是什么?可以使用内置类完成吗?

4 个答案:

答案 0 :(得分:33)

首先,我要说你不能保证独特的结果。如果您想要宇宙中所有字符串的唯一结果,那么最好存储字符串本身(或压缩版本)。

更多关于这一点。让我们首先得到一些哈希值。

hashlib方式

您可以使用任何主要的加密哈希来通过几个步骤对字符串进行哈希处理:

>>> import hashlib
>>> sha = hashlib.sha1("I am a cat")
>>> sha.hexdigest()
'576f38148ae68c924070538b45a8ef0f73ed8710'

就内置插件而言,您可以选择SHA1,SHA224,SHA256,SHA384,SHA512和MD5。

这些哈希算法之间的区别是什么?

哈希函数通过获取可变长度的数据并将其转换为固定长度的数据来工作。

hashlib内置的每个SHA算法的情况下,固定长度是名称中指定的位数(sha1除外是160位)。如果您希望更好地确定两个字符串不会在同一个存储桶中结束(相同的哈希值),请选择具有更大摘要(固定长度)的哈希值。

按照排序顺序,这些是您必须使用的摘要大小:

Algorithm  Digest Size (in bits)
md5        128
sha1       160
sha224     224
sha256     256
sha384     384
sha512     512

摘要越大,你碰撞的可能性就越小,只要你的哈希函数值得它的盐。

等等,hash()怎么办?

内置的hash()函数返回整数,这也可以很容易地用于你概述的目的。但是有问题。

>>> hash('moo')
6387157653034356308
  1. 如果您的程序要在不同的系统上运行,则无法确定hash将返回相同的内容。实际上,我使用64位Python在64位盒子上运行。这些值将与32位Python完全不同。

  2. 对于Python 3.3+,正如@gnibbler所指出的,hash()在运行之间是随机的。它适用于单次运行,但几乎肯定不会在您的程序运行中工作(从您提到的文本文件中提取)。

  3. 为什么hash()会以这种方式构建?好吧,内置哈希有一个特定的原因。哈希表/字典/在内存中查找表。不是用于加密,而是用于在运行时进行廉价查找。

    请勿使用hash(),请使用hashlib

答案 1 :(得分:6)

您只需使用base64模块即可实现目标:

>>> import base64
>>> a = 'helloworld'
>>> encoded_str = base64.encodestring(a)
>>> encoded_str
'aGVsbG93b3JsZA=='
>>> base64.decodestring(encoded_str)
'helloworld'
>>>

当然你也可以使用hashlib模块,它更安全,因为散列字符串不能(或非常非常难)被解码后,但对于你的问题base64就足够了 - “它真的没有安全“

答案 2 :(得分:4)

请注意,Python的字符串哈希不是“已定义” - 它可以并且确实在不同版本和实现之间变化。因此,存储Python字符串哈希会产生困难。 CPython的字符串哈希也不会尝试“模糊”。

标准方法是使用哈希函数设计来做这种事情。像这样:

>>> import hashlib
>>> encoded = hashlib.sha1("abcdef") # "abcdef" is the password
>>> encoded.hexdigest()
'1f8ac10f23c5b5bc1167bda84b833e5c057a77d2'

那长串的十六进制数字是“哈希”。 SHA-1是一个“强大的”哈希函数。如果你找到两个散列到相同值的字符串,你就会出名;-)并且给定相同的输入,它将在所有版本和Python的实现上的所有平台上返回相同的“hexdigest”。

答案 3 :(得分:0)

只需使用hash()内置功能,例如:

s = 'a string'
hash(s)
=> -8411828025894108412