我试图通过使用字符串的哈希值来节省空间。我有一个非常具体的要求,其简化描述如下:
我有两组字符串值,并在运行时提供了一个值。我需要从第二个集合中获取所有字符串的列表,该列表以第一个集合中的字符串开头,并以查询值结束。这是一个显着简化的表示和描述:
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
我的搜索尝试找到支持此属性的哈希函数,但很可能由于没有使用正确的搜索关键字而失败,所以即使您可以为我上面描述的内容描述正确的术语,它也会帮助
答案 0 :(得分:3)
这是一个:
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 :(得分:-2)
您可以使用一些主流哈希算法并尝试使用在线数据库来破解它。如果x和y足够短,您可能会在MD5或SHA在线破解哈希数据库中找到它,如果您对其进行解密,则可以继续使用算法。
如果您的应用程序在线,则可以使用该方法。缺点是在某些极端情况下,您可能会得到错误的值,该值具有与正确的哈希码相同的哈希码,但其概率非常低。
这基本上是一种黑客行为,但你正在根据自己的要求做这类事情,所以你可能会接受。
以下是在线哈希数据库的示例: