Java MessageDigest не работает

Не могу заставить работать MessageDigest, программа выдает две ошибки: UnsupportedEncodingException, NoSuchAlgorithmException

 byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
 MessageDigest md = MessageDigest.getInstance("MD5");
 byte[] Digest = md.digest(bytesOfchat_key);

Если я выдаю ошибки, он дает мне ワ￟ᄡ9ᅦヌnp>0xd￉z в качестве ответа (16 символов)

PS: я использовал для печати Дайджест

for (byte b : Digest) {
    System.out.print((char)b);
}

person rodi    schedule 04.10.2011    source источник


Ответы (3)


md5 возвращает шестнадцатеричные числа, поэтому для декодирования его в строку вы можете использовать

String plaintext = "lol";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
//Decoding
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
while(hashtext.length() < 32 ){
  hashtext = "0"+hashtext;
}
person NCode    schedule 04.10.2011

Программа не выдает эти ошибки — вы вызываете методы, которые могут генерировать эти исключения, поэтому вам нужны блоки catch для них или объявляете, что ваш метод их генерирует слишком.

Результатом дайджеста являются двоичные данные, а не текст. Вы не должны не преобразовывать его байт за байтом в текст следующим образом. Если вам нужна строка, есть два распространенных решения:

  • Кодировать каждый байт как пару шестнадцатеричных цифр
  • Используйте кодировку Base64 для всего массива байтов

Каждый из них можно легко реализовать с помощью кодека Apache Commons.

В MessageDigest нет ничего плохого, но я полагаю, что у вас есть ошибочное представление о том, как работают исключения и как обрабатывать двоичные данные иначе, чем текстовые данные.

person Jon Skeet    schedule 04.10.2011

Байты, сгенерированные MessageDigest, не обязательно представляют собой печатные символы. Вы должны отобразить числовое значение каждого байта или преобразовать массив байтов в строку Base64, чтобы получить что-то для печати.

См. apache commons-codec, чтобы получить реализацию Base64.

Два исключения, которые вы вынуждены обрабатывать, никогда не должны происходить, потому что UTF-8 гарантированно поддерживается любой JVM, а алгоритм MD5 также изначально поддерживается JVM. Таким образом, вы должны обернуть свой код внутри блока try catch следующим образом:

try {
    byte[] bytesOfchat_key = "lol".getBytes("UTF-8");
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] Digest = md.digest(bytesOfchat_key);
}
catch (NoSuchAlgorithmException e) {
    throw new RuntimeException("something impossible just happened", e);
}
catch (UnsupportedEncodingException e) {
    throw new RuntimeException("something impossible just happened", e);
}
person JB Nizet    schedule 04.10.2011