Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java哈希代码反向计算_Java_Int_Hashcode_String Hashing - Fatal编程技术网

Java哈希代码反向计算

Java哈希代码反向计算,java,int,hashcode,string-hashing,Java,Int,Hashcode,String Hashing,我试图通过添加一个新字符并反向减去它来测试Stringhashcode是如何工作的,但是当我进行计算时,它没有给我正确的答案 比如说 int PRIME = 31; //this will print 1687846330 System.out.println("mlkjihgfedcb".hashCode()); //this will print 783628775 which equals to "mlkjihgfedcba".hashCode(); System.out.pr

我试图通过添加一个新字符并反向减去它来测试
String
hashcode是如何工作的,但是当我进行计算时,它没有给我正确的答案

比如说

int PRIME = 31;

//this will print 1687846330 
System.out.println("mlkjihgfedcb".hashCode());   

//this will print 783628775 which equals to "mlkjihgfedcba".hashCode();
System.out.println(("mlkjihgfedcb".hashCode() * PRIME + (int) 'a')); 

//this will print 25278344 which doesn't equals to "mlkjihgfedcb".hashCode()
System.out.println(("mlkjihgfedcba".hashCode() - (int) 'a') / PRIME); 

我想知道我在上面的最后一步算对了吗?溢出对计算不重要,对吗?

此失败的具体原因是

1687846330 * 31 + 97 = 52323236327
数字52323236327比
int
所能容纳的要大得多,因此信息从左端丢失。通过反转
hashCode()
算法无法恢复该信息

如果你做这个运算,你会发现第二个字符串的哈希代码正好是52323236327 mod 231


更重要的是,从对象到散列码的映射是不透明和不可逆的。仅仅因为它今天以特定的方式实现,并不意味着库的下一个版本必须以相同的方式实现。唯一的保证是冲突的可能性极低(但不为零)。

哈希函数是不可逆函数。
作为证明,考虑一下,只能在哈希代码中的整数范围内存储值,但存在无限数量的字符串。因此,必须有多个具有相同哈希代码的字符串(并且有)

将一个大数字乘以31会导致整数溢出,而使用除以31则无法逆转

但请记住:在Java中使用
int
的算术相当于算术模232。因为31是奇数,所以它有一个模232。因此,31的乘法可以与所述“逆”的乘法相反。即:


这是不可逆的。e、 这在很多方面都是错误的levels@Bill我没有看到人们解释为什么它在那个线程中是不可逆的…你在哪里看到的?如果两个不同的字符串可以产生相同的结果,你就不知道是哪个字符串产生了散列码,因此,您无法反向计算。我们如何获得或计算逆数?您可以使用扩展的欧几里德算法,或使用。后者最容易实现:首先设置
x=a=31
,然后重复
x=x*(2-a*x)
,直到收敛,最多五次。但您不必计算,它是-1108378657我不知道字符串的哈希函数的行为是否可以在不破坏任何使用字符串参数的
switch
语句的情况下改变,因为编译后的代码包含字符串的硬编码哈希值。
int inverse = -1108378657;
// This will print the hashCode of mlkjihgfedcb
System.out.println(("mlkjihgfedcba".hashCode() - (int) 'a') * inverse);