我需要一个给出类似输入的函数返回类似的索引

时间:2011-10-11 23:30:03

标签: python hash indexing

所以我看着哈希函数,并且发现给定2个相似的字符串,即使相差一个比特,结果也会是一个完全不同的哈希键。我实际上需要创建一些独特的id,它具有类似输入的相似特征(将是数百万个字母数字字符串)。

示例:

  • 两个相等的字符串必须具有相同的哈希值。
  • 两个不同的字符串必须具有不同的哈希值。
  • 两个不同的字符串,非常相似,必须有不同的哈希值,但同时彼此之间并不太远。

实现这一目标的好方法是什么?我正在使用python。

3 个答案:

答案 0 :(得分:1)

你要求的是不可能的,假设通过'类似哈希'你的意思是值应该具有相似的幅度 - 例如,12345类似于12346而不是92345.原因是相似性这种排序是一维的(数字线),但是字符串彼此相似的方式没有固定的维度(例如,'foo','fob'和'fod'彼此之间的距离都是1)。

如果您想执行模糊匹配,则需要使用其他方法为文字编制索引,例如thisthis

如果您只是想比较相似的各个值,请不要首先对它们进行哈希处理 - 只需立即计算它们的编辑距离。

答案 1 :(得分:0)

如果您确定总是使用字母数字数据,而不是我建议使用基本36(或更高)算法。

您可以使用我提供的方法作为此问题的答案:Base 62 conversion

import string
BASE_LIST = string.digits + string.letters
BASE_DICT = dict((c, i) for i, c in enumerate(BASE_LIST))

def base_decode(string, reverse_base=BASE_DICT):
    length = len(reverse_base)
    ret = 0
    for i, c in enumerate(string[::-1]):
        ret += (length ** i) * reverse_base[c]

    return ret

def base_encode(integer, base=BASE_LIST):
    length = len(base)
    ret = ''
    while integer != 0:
        ret = base[integer % length] + ret
        integer /= length

    return ret

使用示例:

for i in range(100):                                    
    print i, base_decode(base_encode(i)), base_encode(i)

答案 2 :(得分:0)

我相信以下内容符合您的要求。

def gethash(data):
  u"given a character string return an integer hash value"
  return reduce(lambda b1, b2: (b1 << 8) + b2,
      imap(ord, unicodedata.normalize('NFC', data).encode('UTF-8')))

本质上,哈希值是输入的UTF-8编码字节值的完整二进制值,作为单个整数。类似的字符串产生具有相似位的哈希值(并不总是具有小的减法差异,但您没有指定)。规范化导致字符串u'A\u030a'u'\xc5'具有相同的哈希值。

如果你想限制最大值,那么只需应用模数除法(可能是2 ^ 32)作为最后一步。