从输出中查找哈希加密输入

Find a hash encryption input from an output

我有这个函数 hash() 可以将给定的字符串加密为整数。

letters = 'weiojpknasdjhsuert'

def hash(string_input):
  h = 3

  for i in range(0, len(string_input)):
    h = h * 43 + letters.index(string_input[i])

  return h

所以如果我这样做 print(hash('post')),我的输出是:11231443

如果输入只能是来自 letters 的字符串,我如何找到我的输入需要什么才能得到像 1509979332193868 这样的输出?循环体内有一个公式,但我不知道如何反转它。

似乎因为 43 比您的字母表大,所以您可以倒转数学。我不知道如何证明 没有散列冲突,所以这可能有边缘情况。例如:

letters = 'weiojpknasdjhsuert'

def hash(string_input):
    h = 3

    for i in range(0, len(string_input)):
        h = h * 43 + letters.index(string_input[i])

    return h

n = hash('wepostjapansand')
print(n)
# 9533132150649729383107184

def rev(n):
    s = ''
    while n:
        l = n % 43  # going in reverse this is the index of the next letter
        n -= l      # now reverse the math...subtract that index
        n //= 43    # and divide by 43 to get the next n
        if n:
            s = letters[l] + s
    return s

print(rev(n))
# wepostjapansand

使用更合理的字母表,如小写 ascii 和 space,这似乎还可以:

from string import ascii_lowercase 

letters = ascii_lowercase + ' '

def hash(string_input):
    h = 3

    for i in range(0, len(string_input)):
        h = h * 43 + letters.index(string_input[i])

    return h

n = hash('this is some really long text to test how well this works')
print(n)
# 4415562436659212948343839746913950248717359454765313646276852138403823934037244869651587521298

def rev(n):
    s = ''
    # with more compact logic
    while n > 3:
        s = letters[n % 43] + s
        n = (n - (n % 43)) // 43
    return s

print(rev(n))
# this is some really long text to test how well this works

基本思路是,在所有数学运算之后,最后一个数字是:

prev * 43 + letter_index

这意味着您可以通过取 prev 模数 43 来恢复最终字母索引。然后减去它并除以 43(这只是数学的逆运算)并再次执行直到您的数字是零。