【java】文字列をMD5ハッシュ化


与えられた文字列をMD5でハッシュ値に変換する方法のメモ

 


 



java.security.MessageDigestを使って変換していく。
ソース冒頭に「java.security.MessageDigest」と「java.security.NoSuchAlgorithmException」のimportが必要。
面倒なので「java.security.*」をimportしてしまってもよい。

// ①適当な文字列を用意  
String plainText = "abcdefgh";  

// ②MessageDigestのインスタンスを生成
MessageDigest md = MessageDigest.getInstance(“MD5”);

// ③文字列のバイト列をupdate
md.update(plainText.getBytes());

// ④変換後バイト列を取得
byte[] hashBytes = md.digest();

// ⑤16進数に変えつつ桁数を補正
int[] hashInts = new int[hashBytes.length];
StringBuilder sb = new StringBuilder();
for (int i=0; i < hashBytes.length; i++) {
hashInts[i] = (int)hashBytes[i] & 0xff;
if (hashInts[i] <= 15) {
sb.append(“0”);
}
sb.append(Integer.toHexString(hashInts[i]));
}

// ⑥標準出力
String hashText = sb.toString();
System.out.println(“Original Text:” + plainText);
System.out.println(“MD5 Hash Text:” + hashText);


結果は以下の通りになる↓

Original Text:abcdefgh  
MD5 Hash Text:e8dc4081b13434b45189a720b77b6818  



■②でgetInstanceに与える引数の文字列はハッシュ化アルゴリズムを示す文字列で、
 存在しないアルゴリズム文字列を指定するとNoSuchAlgorithmExceptionが発生するつくり。
 よってthrowsしないなら周辺部をtry-catchで囲う必要がある。

■④で返ってくるのはbyteの配列で、要素数は16で固定。
 最終的にこれをMD5ハッシュ値となる32桁の文字に変換する。
 つまり1要素を2桁に変換する感じ。
 1要素のbyte値を2桁の16進数に変換していく。

■16進数への変換に関しては、
 一度intに変換(0xffをかけてスライド)してから16進数にする(Integer#toHexString)。これが⑤。
 このとき、15以下の値(3とかa(10進の10)とかfとか(10進の15))は桁数が1桁になってしまうので、
 文字列にする際に先頭に"0"を補正して桁数が2桁になるように調整する。

この例では文字列"abcdefgh"を変換していっているが、
別に"あ"とかの全角文字でも変換可能だし、
"1"とかの1桁の数値だけでも変換可能である。
(内部的には文字コードをbyteにして渡しているだけだから)
このようなINPUTに対して、結果は全て32桁の文字列になる。



余談。

最初、勘違いしていたのだが、
MD5は「ハッシュ化」であって、暗号化とは違うので、複合化はできない。
よって、MD5ハッシュ化された文字列に対して元のデータが何であったかはわからない。
ただ、wikipediaによれば、同じハッシュ値になる別のデータを見つける実装は世間的に広く認知されているようである。
(俺は知らないけど)