【问题标题】:How to translate to JavaScript this custom MD5 Java function如何将此自定义 MD5 Java 函数转换为 JavaScript
【发布时间】:2011-05-24 12:59:59
【问题描述】:

我有这个自定义函数来计算 MD5 哈希,用 Java 编写。我无法改变它。我需要将它翻译成 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);
}

【问题讨论】:

  • 如果你在 google 上输入:"md5 javascript" 有很多现有的库
  • 但可能没有此 custom MD5 的库
  • 已经给出了解决方案,但是你不应该命名这个 custom MD5 - 它不是一个自定义的 MD5(没有这样的东西 - 如果它是自定义的,它是没有MD5),它只是MD5的自定义编码。

标签: java javascript md5 porting


【解决方案1】:

在此处查看此部分:

  MessageDigest algorithm = null;
  try{
     algorithm = MessageDigest.getInstance("MD5");
  }catch(NoSuchAlgorithmException e){}

?这就是访问 Java 运行时内置的 MD5 代码的地方。您必须在那里提出自己的 MD5 实现,这(说得委婉些)将是棘手的部分.

所发布的 Java 代码真正所做的(除了调用运行时进行实际散列)是通过字符查找表映射生成的散列(无论如何,它的一部分)。

edit — 由该 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('');
}

【讨论】:

  • 你是对的!我的问题是:如何在 JavaScript 中管理 char 数组?
  • JavaScript 字符串的工作方式或多或少类似于 Java char 数组,至少在某种程度上如此。当然,出于该映射的目的,JavaScript 字符串应该可以工作。我会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
  • 2020-06-07
相关资源
最近更新 更多