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

发布于 2024-11-09 13:29:53 字数 1104 浏览 0 评论 0原文

我有这个用 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);
}

I have this custom function to calculate MD5 hash, written in Java. I can't change it. I need to translate it to JavaScript to use it on client side. I tried on my own but I can't manage with JavaScript data types (expecially Java char[])... Any help is appreciated, thanks!

// 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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稍尽春風 2024-11-16 13:29:53

在这里查看这部分:

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

: strong>由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('');
}

See this part here:

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

? That's where that stuff is accessing the MD5 code that's built into the Java runtime. You'll have to come up with your own implementation of MD5 there, which (to put it mildly) will be the tricky part.

All that the posted Java code really does (on top of calling the runtime to do the actual hashing) is to map the resulting hash (part of it, anyway) through a character lookup table.

edit — the lookup table built by that Java code is an array with "$", the digits, the upper-case letters, the lower-case letters, and then (surprisingly) "£". (The last character is surprising because it's not an old-school 7-bit ASCII character code, but whatever.) In JavaScript, that's:

var codes = "$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz£";

The Java code then takes each 8-bit byte produced by the hash algorithm and looks up a code character by adding 128 to the byte and then dividing by 4. Java bytes are treated as signed values, so that has the effect of mapping every byte into the range 0 ... 63. That value is then used as a lookup into the code array.

Thus if you have a JavaScript MD5 facility that can give you back an array of numbers in the range -128 ... 127 (that is, signed 8-bit values), you could translate the result through the code array like this:

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

EDIT by the OP:
I take the liberty of posting here the right solution, that is highly derived from @Pointy's one. It requires md5.js from http://pajhome.org.uk/crypt/md5/.

/* 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('');
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文