我有这个自定义函数来计算用Java编写的MD5哈希。我无法改变它。我需要将其翻译为JavaScript以在客户端使用它。我尝试了自己但我无法管理JavaScript数据类型(特别是Java char[]
)...感谢所有帮助,谢谢!
// codes array
char[] codes = new char[64];
// initialise
private void initCodes(){
codes = new char[64];
codes[0] = '$';
int count = 0;
for (char i='0';i<='9';i++){ count++; codes[count] = i; }
for (char i='A';i<='Z';i++){ count++; codes[count] = i; }
for (char i='a';i<='z';i++){ count++; codes[count] = i; }
codes[63] = '£';
}
// custom MD5 algorithm
public String customMD5(String source) {
initCodes();
byte[] buf = new byte[source.length()];
buf = source.getBytes();
MessageDigest algorithm = null;
try {
algorithm = MessageDigest.getInstance("MD5");
} catch(NoSuchAlgorithmException e){}
algorithm.reset();
algorithm.update(buf);
byte[] digest = algorithm.digest();
int len = digest.length;
char[] encrypted = new char[len];
for (int i=0;i<len;i++)
encrypted[i] = codes[(int)(Math.floor((double)((digest[i]+128)/4)))];
return new String(encrypted);
}
答案 0 :(得分:2)
在此处查看此部分:
MessageDigest algorithm = null;
try{
algorithm = MessageDigest.getInstance("MD5");
}catch(NoSuchAlgorithmException e){}
?那就是那些东西正在访问内置于Java运行时的的MD5代码。你必须在那里提出你自己的MD5实现,(温和地说)将是棘手的部分
发布的Java代码所做的一切(在调用运行时进行实际散列之上)都是通过字符查找表映射结果哈希(无论如何)。
编辑 - 由Java代码构建的查找表是一个带有“$”的数组,数字,大写字母,小写字母,然后(令人惊讶的)“£ ”。 (最后一个字符是令人惊讶的,因为它不是一个老式的7位ASCII字符代码,但无论如何。)在JavaScript中,那是:
var codes = "$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz£";
然后,Java代码获取由散列算法生成的每个8位字节,并通过向字节添加128然后除以4来查找代码字符.Java字节被视为有符号值,因此具有将每个字节映射到0 ... 63范围内。然后将该值用作对代码数组的查找。
因此,如果您有一个JavaScript MD5工具可以返回-128 ... 127范围内的数字数组(即带符号的8位值),您可以通过代码数组转换结果这样:
var digest = MagicJavaScriptMD5(source);
var result = [];
for (var i = 0; i < digest.length; ++i)
result.push(codes.charAt(~~((digest[i] + 128) / 4)));
var resultString = result.join('');
OP编辑: 我冒昧地在这里发布正确的解决方案,这非常源于@ Pointy的一个。它需要来自http://pajhome.org.uk/crypt/md5/的md5.js。
/* MD5 in byte[] format */
function byteArray_md5(s) {
var output = [];
var input = rstr_md5(str2rstr_utf8(s)); //here it uses md5.js
for(var i = 0; i < input.length; i++)
output[i] = input.charCodeAt(i);
return output;
}
/* MD5 with custom mapping.
* It's a normal MD5 with a final char mapping of the hash.
*/
function md5WithCustomMapping(source) {
var codes = "$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz£";
var digest = byteArray_md5(source);
var result = [];
for (var i = 0; i < digest.length; ++i)
result.push(
codes.charAt(
~~( ( digest[i] + 128 * (digest[i]<128 ? 1 : -1) )/4 )
)
);
return result.join('');
}