Java計算ファイルMD 5値
ファイルアップロードダウンロードに関する操作では、通常、ファイルMD 5を計算する必要があるシーンに遭遇します.ファイルMD 5の値を計算する方法は、文字列のMD 5の値を計算する方法と似ています.ここでは、通常の文字列を計算するMD 5の方法について説明します.
commons-codecというjarは私たちにMD 5実現を提供してくれました.普通のMD 5実現は、基本的に大同小異で、最終的な結果も同じです.ここではあまりにも過言ではありません.なぜ普通のMD 5と呼ばれているのか.実現の構想は同じで、同じ文字列であれば、計算の結果も同じなので、解読されやすいからです.MD 5というアルゴリズム自体は不可逆的であるが,レインボーテーブルの解読方式やオンライン解読によれば,よく使われるパスワードのいくつかは容易に推測できる.
まずcommons-codecが提供するMD 5の実装を見てみましょう.
DigestUtils.md5Hex(String source);
このような簡単なコードはMD 5アルゴリズムを実現するのに役立ちます.
commons-codecで提供されていないapiも多く、java security apiを使用してMD 5アルゴリズムを実装しています.ここでは簡単な例を示します.
よく見られるMD 5アルゴリズムは長いと信じられていますが、その中で、私たちが見ている複雑な部分はバイト配列の16進法を行うことです.実はjavaが提供したapiはMD 5コアアルゴリズムを完成させるのに役立ちました.私たちがここで行ったバイト配列の16進数は、実はこのアルゴリズムの氷山の一角です.
もちろんバイト配列が16進数になるのも、いろいろな方法があるので、この方法にもいろいろな変種があります.
public static String buffer2Hex3(byte[] data){ StringBuffer sb = new StringBuffer(); for(int i=0;i int d1 = data[i]; if(d1<0){ d1 = d1 & 0xff; } if(d1<16){ sb.append("0"); } sb.append(Integer.toHexString(d1)); } return sb.toString(); } BigIntegerによる直接16進法:public static String buffer 2 Hex 4(byte[]data){BigInteger res=new BigInteger(1,data);return res.toString(16);}
もちろん、前の文字列配列を文字配列で置き換えるアルゴリズムもあります.
private static final char[] digestHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
public static String buffer2Hex2(byte[] data){ StringBuffer sb = new StringBuffer(); for(int i=0;i byte d = data[i]; char d1 = digestHex[(d & 0xf0) >> 4]; char d2 = digestHex[d & 0xf]; sb.append(d1); sb.append(d2); } return sb.toString(); }
これらの異なる実装は,コアのアルゴリズムがバイト配列回転16進法であることを知っている.では、ファイルにとってMD 5をどのように計算するかは、ファイルをバイト配列に変換すれば、この後のバイト配列を16進数に変換する方法を組み合わせることができるのではないかと考えてみましょう.実際、確かに、ファイルをメモリに読み込み、バイト配列に変換するだけで、文字列を求めるMD 5の方法と同じです.
commons-ioはFileUtilsを提供した.readFileToByteArray(File file)というapiは,byte[]タイプのバイト配列を得る.ファイルを求めるMD 5アルゴリズムはこのように簡単に実現されました.
public static String md5Hex(File file) { try { return DigestUtils.md5Hex(FileUtils.readFileToByteArray(file)); } catch (IOException e) { e.printStackTrace(); } return null; }
興味があればFileUtilsをreadFileToByteArray(file)メソッドは、IOストリームでファイルをメモリに読み込み、byte[]タイプの配列に変換する簡単な実装に置き換えられます.
一般的な文字列がMD 5で暗号化された後の結果: 123456->e10adc3949ba59abbe56e057f20f883e admin ->21232f297a57a5a743894a0e4a801fc3 111111->96e79218965eb72c92a549dd5a330112 666666->f379eaf3c831b04de153469d1bec345e
私たちはMessageDigestを通じてdigest(byte[])で得られた配列は,元の文字列やファイルがどんなに大きくても,得られたバイト配列は長さが16であるため,10進数から16進数に移行し,結果は32ビットであった.通常のMD 5アルゴリズムが解読される可能性があることを改めて説明した.
commons-codecというjarは私たちにMD 5実現を提供してくれました.普通のMD 5実現は、基本的に大同小異で、最終的な結果も同じです.ここではあまりにも過言ではありません.なぜ普通のMD 5と呼ばれているのか.実現の構想は同じで、同じ文字列であれば、計算の結果も同じなので、解読されやすいからです.MD 5というアルゴリズム自体は不可逆的であるが,レインボーテーブルの解読方式やオンライン解読によれば,よく使われるパスワードのいくつかは容易に推測できる.
まずcommons-codecが提供するMD 5の実装を見てみましょう.
DigestUtils.md5Hex(String source);
このような簡単なコードはMD 5アルゴリズムを実現するのに役立ちます.
commons-codecで提供されていないapiも多く、java security apiを使用してMD 5アルゴリズムを実装しています.ここでは簡単な例を示します.
private static final String[] strHex=
{"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
private static MessageDigest digest = null;
static{
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public static String getMD5(String source){
try {
byte[] data = source.getBytes("UTF-8");
return buffer2Hex(digest.digest(data));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public static String buffer2Hex(byte[] data){
StringBuffer sb = new StringBuffer();
for(int i=0;i
よく見られるMD 5アルゴリズムは長いと信じられていますが、その中で、私たちが見ている複雑な部分はバイト配列の16進法を行うことです.実はjavaが提供したapiはMD 5コアアルゴリズムを完成させるのに役立ちました.私たちがここで行ったバイト配列の16進数は、実はこのアルゴリズムの氷山の一角です.
もちろんバイト配列が16進数になるのも、いろいろな方法があるので、この方法にもいろいろな変種があります.
public static String buffer2Hex3(byte[] data){ StringBuffer sb = new StringBuffer(); for(int i=0;i int d1 = data[i]; if(d1<0){ d1 = d1 & 0xff; } if(d1<16){ sb.append("0"); } sb.append(Integer.toHexString(d1)); } return sb.toString(); } BigIntegerによる直接16進法:public static String buffer 2 Hex 4(byte[]data){BigInteger res=new BigInteger(1,data);return res.toString(16);}
もちろん、前の文字列配列を文字配列で置き換えるアルゴリズムもあります.
private static final char[] digestHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
public static String buffer2Hex2(byte[] data){ StringBuffer sb = new StringBuffer(); for(int i=0;i byte d = data[i]; char d1 = digestHex[(d & 0xf0) >> 4]; char d2 = digestHex[d & 0xf]; sb.append(d1); sb.append(d2); } return sb.toString(); }
これらの異なる実装は,コアのアルゴリズムがバイト配列回転16進法であることを知っている.では、ファイルにとってMD 5をどのように計算するかは、ファイルをバイト配列に変換すれば、この後のバイト配列を16進数に変換する方法を組み合わせることができるのではないかと考えてみましょう.実際、確かに、ファイルをメモリに読み込み、バイト配列に変換するだけで、文字列を求めるMD 5の方法と同じです.
commons-ioはFileUtilsを提供した.readFileToByteArray(File file)というapiは,byte[]タイプのバイト配列を得る.ファイルを求めるMD 5アルゴリズムはこのように簡単に実現されました.
public static String md5Hex(File file) { try { return DigestUtils.md5Hex(FileUtils.readFileToByteArray(file)); } catch (IOException e) { e.printStackTrace(); } return null; }
興味があればFileUtilsをreadFileToByteArray(file)メソッドは、IOストリームでファイルをメモリに読み込み、byte[]タイプの配列に変換する簡単な実装に置き換えられます.
一般的な文字列がMD 5で暗号化された後の結果:
私たちはMessageDigestを通じてdigest(byte[])で得られた配列は,元の文字列やファイルがどんなに大きくても,得られたバイト配列は長さが16であるため,10進数から16進数に移行し,結果は32ビットであった.通常のMD 5アルゴリズムが解読される可能性があることを改めて説明した.