От строки к шестнадцатеричному MD5 хешу и обратно - PullRequest
1 голос
/ 11 июня 2010

У меня есть этот псевдокод в Java:

bytes[] hash = MD5.hash("example");

String hexString = toHexString(hash); //This returns something like a0394dbe93f

bytes[] hexBytes = hexString.getBytes("UTF-8");

Теперь hexBytes[] и hash[] различны.

Я знаю, что делаю что-то не так, поскольку hash.length() - это 16, а hexBytes.length() - это 32. Возможно, это как-то связано с использованием Java с использованием Unicode для символов (просто дикая догадка).

В любом случае, вопрос будет: как получить исходный массив hash[] из hexString.

Весь код здесь, если вы хотите посмотреть на него (это ~ 40 LOC) http://gist.github.com/434466

Вывод этого кода:

16
[-24, 32, -69, 74, -70, 90, -41, 76, 90, 111, -15, -84, -95, 102, 65, -10]
32
[101, 56, 50, 48, 98, 98, 52, 97, 98, 97, 53, 97, 100, 55, 52, 99, 53, 97, 54, 102, 102, 49, 97, 99, 97, 49, 54, 54, 52, 49, 102, 54]

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 11 июня 2010

Вы просто получаете байты шестнадцатеричной строки с hexString.getBytes("UTF-8");, не преобразуя шестнадцатеричные цифры в их байтовые значения.

То есть вам нужно написать обратную функцию toHexString.Вероятно, ваша строка toHexString должна форматировать значения ниже 10–2 цифр, например, например, байт 9 заканчивается как «09», а не «9».

2 голосов
/ 11 июня 2010

Вы не показали toHexString, но в основном вам нужен обратный эквивалент - ищите метод с именем fromHexString или что-то подобное.

В основном String.getBytes() выполняет нормальное кодирование (в данном случае в UTF-8). Вы хотите эффективно декодировать текст - текстовое представление произвольных двоичных данных - в byte[].

Кодек Apache Commons имеет соответствующие методы - API не идеален, но он будет работать:

byte[] data = ...;
String hex = Hex.encodeHexString(data);
...

byte[] decoded = (byte[]) Hex.decode(hex);
1 голос
/ 11 июня 2010

Если вы не хотите использовать библиотеку, вот как вы можете это сделать с моей версией шестнадцатеричного декодера,

byte[] hexBytes = dehexify(hexString);

public static byte[] dehexify(String hexString) {
    if (hexString.length()%2 == 1)
        throw new IllegalArgumentException("Invalid length");       
    int len = hexString.length()/2;
    byte[] bytes = new byte[len];
    for (int i=0; i<len; i++) {
        int index = i*2;
        bytes[i] = (byte)Integer.parseInt(hexString.substring(index, index+2), 16);
    }
    return bytes;
}
1 голос
/ 11 июня 2010

getBytes () не анализирует шестнадцатеричные символы, он обрабатывает кодировки символов. Другими словами, он не превращает «0A» в 0x0A, но в 0x30 0x41, потому что так кодируются символы «0» и «A». Вы хотите Integer.parseInt(String, radix) вместо этого в своей функции, с основанием == 16.

...