如何将这个自定义MD5 Java函数转换为JavaScript

时间:2011-05-24 13:00:00

标签: java javascript md5 porting

我有这个自定义函数来计算用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);
}

1 个答案:

答案 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('');
}