0

我必须使 java 函数与 jQuery 兼容。jQuery Real Person captcha validate 函数是由 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; 
} 
4

1 回答 1

3

如果您发布预期结果(来自 Java)和实际结果(来自 JavaScript),将会有所帮助。我用字符串测试了它,"abc"Java 函数返回193450027,而 JavaScript 版本返回"00177573ABC". 从这些结果来看,问题更容易被发现。

问题是您没有正确翻译循环体。hash是一个int,因此((hash << 5) + hash)也是一个int。然而,value.charAt(i)是一个char。当 Java 需要将 an 添加int到 a时会发生什么char?简单:achar是由两个字节表示的 Unicode 字符。char扩展为具有相同 Unicode 值的int,然后添加到int.

但是,JavaScript 的工作方式非常不同。hash is anumbervalue.charAt(i)is astring一个字符。将 a 添加number到 astring时, the+被解释为两个s 的串联string,因此结果也是 a string。由于 JavaScript 不是静态类型的,因此将 的值hash从 更改number为是完全合法的string

在进一步的迭代中,hash将(很可能)是string同时持有数字和非数字字符。因此,在评估 时,移位操作所需的从 a到 ahash << 5的隐式转换会默默地失败并返回。由于与上述相同的原因,以及成为连接。stringnumber0+ hash+ value.charAt($i)

因此,正确的翻译是检索字符代码而不是字符

hash = ((hash << 5) + hash) + value.charCodeAt($i);

这将正确地导致预期添加两个numbers。

在不相关的注释中,您应该编写var $i = 0而不是$i = 0在您的 for 初始化中,以防止泄漏$i到全局范围。这同样适用于hash,应声明为var hash = 5381。此外,约定是带有前缀的变量$代表一个 jQuery 对象,但$i事实并非如此。你最好把它命名为iJava。

于 2013-01-31T11:23:47.677 回答