Java 短字符串的哈希代码可以相同吗?

Java 短字符串的哈希代码可以相同吗?,java,string,hashcode,hash-collision,Java,String,Hashcode,Hash Collision,我有短字符串s(少于10个字符)。我将它转换为int,并将其用作主键。(由于小问题,我不能使用字符串主键。)我知道无限长字符串的哈希码会发生冲突,但短字符串也会发生冲突吗?哈希码的大小为32位 Java中的char大小为16位 因此,理论上,所有2个字符的字符串都可能有不同的哈希代码,尽管其中一些哈希代码必须与空字符串和单个字符字符串的哈希代码冲突。因此,即使采用“两个字符或更短的所有字符串”,也会出现冲突。当您有10个字符时,可能的字符串比可用的哈希代码多得多 碰撞仍然很可能是罕见的,但你应该

我有短
字符串
s(少于10个字符)。我将它转换为
int
,并将其用作主键。(由于小问题,我不能使用字符串主键。)我知道无限长字符串的哈希码会发生冲突,但短字符串也会发生冲突吗?

哈希码的大小为32位

Java中的
char
大小为16位

因此,理论上,所有2个字符的字符串都可能有不同的哈希代码,尽管其中一些哈希代码必须与空字符串和单个字符字符串的哈希代码冲突。因此,即使采用“两个字符或更短的所有字符串”,也会出现冲突。当您有10个字符时,可能的字符串比可用的哈希代码多得多


碰撞仍然很可能是罕见的,但你应该始终假设它们会发生。

绝对是的。例如,
Ea
FB
是冲突字符串,每个字符串的长度只有两个字符!例如:

public static final void main(String[] args) {
    System.out.println("Ea".hashCode() + " " + "FB".hashCode());
}
打印
22362236


Java
String#hashCode
函数实际上甚至不接近随机。短字符串很容易产生冲突,而长字符串的情况也不太好


一般来说,即使您坚持每个字符只有6位(ASCII字母和数字,以及两个符号),您也会超过32位哈希代码的可能值,只有6个字符的字符串——也就是说,您绝对会保证2^36个6个字符的6位字符串之间的冲突。

+1用于直接[counter-]示例。看到一个字符串/散列冲突图会很有趣,它可能已经存在。事实上,这可以用来创建拒绝服务攻击,将散列图的O(1)行为转化为O(N):@yshavit问题用Java 8解决,在您发表评论前几个月发布;^)@霍尔格是什么让你突然想到这个问题的-P@yshavit搜索了其他一些与字符串哈希相关的内容,这些内容在搜索结果中,请参见-大量来自拼字的冲突。一些统计数据:“有3844个大小为2的字母数字字符串。在这3570个字符串中,至少有一个与其他字符串冲突。也就是说,[只有]274个字符串(或大约7%)没有与其他字符串冲突。哦,好吧。没有人会愚蠢到依赖哈希代码来区分两个对象的内容,这是一件好事。”+1指出它(不一定)只是java有一个愚蠢的散列函数,而是一个基本问题。使用生日悖论,即使使用分布良好的散列,对于16k个项目的集合,冲突也不是不寻常的。(有关准确的数字,请参阅。)@MichaelAnderson:我想这取决于你所说的罕见。至少发生一次碰撞的可能性可能相当高,但任何特定对碰撞的可能性都相当小。不管怎么说,我是说你无论如何都要对此负责,所以这没什么大不了的;)@霍尔格,我想你没有抓住我想说的重点。其他答案表明,字符串的Javas散列值的分布对于简单字符串是有害的。这个答案指出,即使有一个完美的散列分布,我们也应该期待冲突。