已知字符串的hash算法如下:
function hashCode(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = hash * 31 + str.charCodeAt(i);
}
return hash;
}
找出2^n个hashCode
方法返回值相同,且长度为2^n的字符串,提示:hashCode('Aa') == hashCode('BB')
。如下图所示:
根据例子可以推论如下:
CC == Bb
DD == Cc
BBBB == BBAa
但是如何找出全部的2^n个字符串还是一点思路都没有
放在主回答里哈。。。
给个思路哈,我们可以认为最终的hash是31进制数,那么我们可以通过以下步骤来从一个字符串构造另一个hashCode相同的字符串:
1.某个位置上的code-31
2.它的前一个位置上的code+1
为了得到合法的字符串,我们要保证code-31和code+1得到某个字母的编码。例如:'y'的编码值为121,121-31=90刚好为'Z'的编码值。
接下来来构造吧,首先有一个字符串xxxxxxxxyy(这里x代表任意字母)我们把最后一个y-31,得到'Z',倒数第二个y+1,得到'z',所以hashCode("xxxxxxxxyy")==hashCode("xxxxxxxxzZ")。前面n-2个x可以随机有52^(n-2)个。为什么是52,26个大写字母,26个小写字母。
然后最后两个yy改成xx继续上面的过程。
这样的字符串你可以得到非常多个。
================ 以下是原回答 ===================
题目感觉有点矛盾,如果按照
hashCode
算法的实现,hashCode('Aa')
肯定不等于hashCode('BB')
。下面几组也不可能相等。