2

MessageDigest を機能させることができません。プログラムから次の 2 つのエラーが返されます: 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);
}
4

4 に答える 4

4

md5 は 16 進数を返すため、それを文字列にデコードするには、使用できます

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;
}
于 2011-10-04T12:15:52.343 に答える
1

MessageDigest によって生成されるバイトは、必ずしも印刷可能な文字を表すとは限りません。各バイトの数値を表示するか、バイト配列を Base64 文字列に変換して印刷可能なものにする必要があります。

Base64 の実装を取得するには、apache commons-codecを参照してください。

UTF-8 はすべての JVM でサポートされることが保証されており、MD5 アルゴリズムも JVM でネイティブにサポートされているため、処理を余儀なくされる 2 つの例外は決して発生しないはずです。したがって、コードを次のように 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);
}
于 2011-10-04T12:19:41.540 に答える
1

プログラムはこれらのエラーを表示しません。これらの例外をスローできるメソッドを呼び出しているため、それらの catch ブロックが必要になるか、メソッドもそれらをスローすることを宣言します。

ダイジェストの結果は、テキストではなくバイナリデータです。このようにバイトごとにテキストに変換しないでください。文字列として必要な場合は、2 つの一般的な解決策があります。

  • 各バイトを 16 進数のペアとしてエンコードする
  • 完全なバイト配列で Base64 エンコーディングを使用する

これらはそれぞれ、Apache Commons Codecを使用して簡単に実装できます。

に問題はありませんがMessageDigest、例外のしくみや、バイナリ データをテキスト データとは異なる方法で扱う方法についての理解に問題があると思います。

于 2011-10-04T12:16:13.153 に答える