我必须使用jQuery兼容java函数。 jQuery Real Person captcha验证函数由java编写。我想在jQuery中验证验证码。所以,我试着在jQuery中编写java函数。但是该功能无法返回正确的值。
爪哇:
private String rpHash(String value) {
int hash = 5381;
value = value.toUpperCase();
for(int i = 0; i < value.length(); i++) {
hash = ((hash << 5) + hash) + value.charAt(i);
}
return String.valueOf(hash);
}
jQuery的:
function rpHash(value) {
hash = 5381;
value = value.toUpperCase();
for($i = 0; $i < value.length; $i++) {
hash = ((hash << 5) + hash) + value.charAt($i);
}
return hash;
}
答案 0 :(得分:3)
如果您发布预期结果(来自Java)和实际结果(来自JavaScript),它会有所帮助。我使用字符串"abc"
对其进行了测试,Java函数返回193450027
,而JavaScript版本返回"00177573ABC"
。看看这些结果,问题就更容易发现了。
问题是你没有正确翻译循环体。 hash
是int
,因此((hash << 5) + hash)
也是int
。但是,value.charAt(i)
是 char
。当Java需要向int
添加char
时会发生什么?简单:char
是由两个字节表示的Unicode字符。 char
扩展为具有相同Unicode值的int
,然后添加到int
。
然而,JavaScript的工作方式却截然不同。 hash
是number
,value.charAt(i)
是string
,只有一个字符。向number
添加string
时,+
被解释为两个string
的连接,因此结果也是{ {1}}。由于JavaScript不是静态类型,因此将string
的值从hash
更改为number
是完全合法的。
在进一步的迭代中,string
将(很可能)是一个hash
,同时包含数字和非数字字符。因此,在评估string
时,转移操作所需的从hash << 5
到string
的隐式转换会无声地失败并返回number
。由于与上述相同的原因,0
以及+ hash
会成为连接。
因此,正确的翻译是检索字符代码而不是字符:
+ value.charAt($i)
这将正确地导致预期添加两个hash = ((hash << 5) + hash) + value.charCodeAt($i);
s。
在不相关的说明中,您应该在初始化中编写number
而不是var $i = 0
,以防止$i = 0
泄露到全局范围。这同样适用于$i
,应将其声明为hash
。此外,惯例是前缀为var hash = 5381
的变量表示jQuery对象,而$
则不是。你最好用Java命名它$i
。