Как перевести на JavaScript эту пользовательскую функцию Java MD5 - PullRequest
0 голосов
/ 24 мая 2011

У меня есть эта пользовательская функция для вычисления хеша 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);
}

1 Ответ

2 голосов
/ 24 мая 2011

Смотрите эту часть здесь:

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

? Вот где этот материал обращается к коду MD5, который встроен в среду выполнения Java. Вам придется придумать там свою собственную реализацию MD5, которая (мягко говоря) будет сложной частью.

Все, что действительно делает опубликованный Java-код (помимо вызова среды выполнения для фактического хеширования), - это отображение полученного хеша (в любом случае его части) через таблицу поиска символов.

edit & mdash; таблица поиска, созданная этим 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. Требуется md5.js от 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('');
}
...