【问题标题】:Is there a string hash function that supports h(x) + h(y) = h(x+y)是否有支持 h(x) + h(y) = h(x+y) 的字符串哈希函数
【发布时间】:2015-03-16 08:18:23
【问题描述】:

我正在尝试通过使用字符串的哈希值来节省空间。我有一个很具体的要求,简述如下:

我有两组字符串值,并且在运行时提供了一个值。我需要从第二组中获取所有字符串的列表,该列表以第一组中的字符串开头并以查询值结尾。这是一个显着简化的表示和描述:

set1:
my_test_val_1
my_test_val_2

set2:
my_test_val_1_extended_to_another_value
my_test_val_2_extended_as_well

我的目标是保持这些集合的哈希值如下:

set1:
hash(my_test_val_1)
...

set2:
hash(my_test_val_1_extended_to_another_value)

为了节省空间,当 '_extended_to_another_value' 作为查询到达时,请使用具有分配属性的哈希函数来执行以下操作:

hash(my_test_val_1) + hash('_extended_to_another_value') = hash_value_to_search

我的搜索尝试找到支持此属性的哈希函数很可能是由于没有使用正确的关键字进行搜索,所以即使您可以为我上面描述的内容描述正确的术语,它也会有所帮助

【问题讨论】:

  • 您是否依赖只是保留哈希值?处理哈希冲突的计划是什么?
  • 您需要生成的哈希函数的哪些属性?最终哈希可以使用多少位?
  • " 需要从第二组中获取所有字符串的列表,该列表以第一组中的字符串开头并以查询值结尾。" Are you looking for a trie?
  • 也许像 prefix hash tree 这样的东西在这里是相关的?
  • @JonSkeet 是的,哈希冲突是一个问题,但我可以忍受低冲突率并伴随一些广泛的测试(这是所有合成数据,所以我可以大规模测试它)看看什么率,如果有的话我有碰撞。

标签: java hash hashcode


【解决方案1】:

这是一个:

import java.util.Random;
public class StringHasher {
    private static int[] CHAR_HASHES = new int[65536];
    static {
        Random rng = new Random();
        for(int k = 0; k < 65536; k++)
            CHAR_HASHES[k] = rng.nextInt();
    }
    public static int hash(String s) {
        int result = 0;
        for(int k = 0; k < s.length(); k++) {
            result += CHAR_HASHES[s.charAt(k)];
        }
        return result;
    }
}

事实证明,任何此类散列必须通过将字符串组成字符的所有散列相加来构造 - 否则例如 h("hello") = h("h") + h("e") + h("l") + h("l") + h("o") 将不成立。

注意:这意味着你不能有一个非常抗冲突的哈希,因为每个包含相同字符的字符串都会有相同的哈希,根据上一段。

平均而言,为每个单字符串的散列选择随机值应该提供接近最佳可能的抗碰撞性。这确实浪费了 256 KiB 的内存,而且不是最快的方法,而且不可重复,但对于概念验证来说已经足够了。

【讨论】:

  • +1 用于观察哈希线性的后果。我会考虑使用素数来填充 CHAR_HASHES。
  • @Krystian 我不知道如何选择字符哈希以获得良好的抗碰撞性(但随机数有效)。
【解决方案2】:

您可以使用一些主流的哈希算法并尝试使用在线数据库对其进行破解。如果 x 和 y 足够短,您可能会在 MD5 或 SHA 在线破解哈希数据库中找到它,如果您对其进行解密,则可以继续使用您的算法。

如果您的应用程序在线,则可以使用该方法。不利的一面是,在某些极端情况下,您可能会得到与正确的哈希码相同的错误值,但这种可能性非常低。

这基本上是一种 hack,但您正在根据您的要求做这种事情,所以它可能对您来说是可以接受的。

这里是一个在线哈希数据库的例子:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2020-04-01
    • 1970-01-01
    • 2019-07-23
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多