【问题标题】:Perfect hash function (i.e. no collisions) with same length [closed]具有相同长度的完美哈希函数(即没有冲突)[关闭]
【发布时间】:2017-04-03 22:30:24
【问题描述】:

我正在寻找一个不会产生冲突的简单哈希函数。

我有一个字母数字序列(比如 16 个字母长),我希望它们中的每一个都映射到唯一的散列值。理想情况下,散列值与原始序列的长度相同(16 个字母长)。

有没有一个简单的python哈希函数可以实现这个?

【问题讨论】:

  • 您已经将其命名为:它被称为“完美哈希函数”,我认为它最早是在 1978 年左右的一篇论文中描述的。你怎么没有在你的文献搜索中找到它?
  • 会是一个简单的密码吗?即从每个字符的 ascii 值中减去 5(并循环以确保所有字符都有效)
  • 听起来身份哈希可以正常工作。如果您想将 16 个字符的序列散列为 16 个字符的序列而不会发生冲突,lambda x: x 可以满足这些要求。
  • 我投票结束这个问题,因为没有定义要求,并且提问者在给出了有效的答案后提出了新的要求。
  • "如果哈希函数的输入是 X,则不能总是返回 X。"为什么不?你需要解释为什么。如果这是一项安全措施,那就令人难以置信。为什么你需要一个完美的哈希,而不是 SHA256?

标签: python hash


【解决方案1】:

使用类似的东西

u"".join([unichr(ord(spl[0])*100 + ord(spl[1])-30) for spl in [instr[i: i + 2] for i in range(0, 16, 2)]])

这是一个非常糟糕的转变:

1234567890123456 变为 ጸᐂᓌᖖᙖጸᐂᓌ

aAzZ09jdmekfADEF 变为 ☇⿤ዛ⦮⫛⨔ᦊᬜ

IamBADatREQUIREM 变为 ᳇⪸ᦊ☺ ΊᲸᬣ

zzaa009990123456 变为 〄☧ዒᙟᙖጸᐂᓌ

通过以下方式反转:

"".join([chr(ord(num) / 100) + chr(ord(num) % 100 + 30) for num in unistring])

u"〄☧ዒᙟᙖጸᐂᓌ" 变为 zzaa009990123456

因此生命的循环是完整的。

【讨论】:

    【解决方案2】:

    如果哈希函数可以返回任何不可变对象,则直接返回字符串。无需将它们映射到任何东西。

    def hash(s):
        return s
    

    如果它需要返回整数,那很简单。 Python 整数可以任意大,因此您只需将字符串转换为具有相同字节的 int。

    def hash(s):
        return int.from_bytes(string.encode(), byteorder='big')
    

    【讨论】:

    • 第一个不可接受。我们不能总是返回原始字符串。这是我的要求之一。假设出于安全原因,我们想映射到其他值
    【解决方案3】:

    哈希函数返回一个相对于哈希函数的固定长度的字符串而不是输入字符串,你想要的是一个密码

    https://crypto.stackexchange.com/questions/8765/is-there-a-hash-function-which-has-no-collisions

    ASCII value of a character in Python

    from random import shuffle
    
    def create_cipher():
    
        key = []
        # ASCII value of numerals
        for i in range(48,58):
            key.append(i)
        # ASCII value of lowercase
        for i in range(65,91):
            key.append(i)
        # ASCII value of uppercase
        for i in range(97,123):
            key.append(i)
        print key
        cipher = list(key)
        shuffle(cipher)
        print cipher
        cipher_dict = {}
        for i in range(len(key)):
            cipher_dict[key[i]] = cipher[i]
        return cipher_dict
    
    def cipher(string,code_dict):
    
        coded_list = []
        list_string = list(string)
        list_string = [ord(i) for i in list_string]
        for i in list_string:
            coded_list.append(code_dict[i])
        coded_list = [chr(i) for i in coded_list]
        return  ''.join(coded_list)
    
    msg = 'HelloWorld2017'
    encode_dict = create_cipher()
    decode_dict = {y:x for x,y in encode_dict.iteritems()}
    encoded_cipher = cipher(msg,encode_dict)
    decoded_cipher = cipher(encoded_cipher,decode_dict)
    
    print msg
    print encoded_cipher
    print decoded_cipher
    
    
    >>>
    HelloWorld2017
    pryyLILoyx9fgm
    HelloWorld2017
    

    您当然想要验证您的输入...对于字母数字,您可以使用:

    isalnum()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      相关资源
      最近更新 更多