MD5的非常有實際應用性。有網友給出這樣的描述,可以參照一下:http://blog.csdn.net/Daping_Zhang/archive/2005/05/28/382688.aspx
該類的
getInstance(String algorithm)
方法返回一個MessageDigest的實體,加密的一系統的digest()
方法和update(byte input)方法。加密後返回一個byte[],16位,我們經常見到很多開源網站的下載地址會有一個[md5]的鏈接,打開其實就是一小段文本內容。例如:
MD5 (commons-logging-1.1.1-bin.zip) = f88520ed791673aed6cc4591bc058b55這是Jakarta的logging組件下載時提供的MD5摘要信息,是對這個zip包進行全文加密生成的摘要,摘要碼就是後面的f88520ed791673aed6cc4591bc058b55,如果你下載以後,按照MD5的算法生成自己的摘要,如果這二個摘要一樣,就證明這個文件是沒有被人篡改過的。
遇到的問題是Java的MessageDigest類執行後返回的byte[16]得轉換成十六進制的字符串,如果直接用new String(byte[]),得到的結果將是不正確的。算法有很多網友提供了,照搬了。比較有趣的是,commons-logging提供的那個MD5居然和我自己生成的不一樣(難道文件被修改過?),後來嘗試了其它地方提供的MD5碼,都沒有問題。
有很多相關的現成代碼,蒐集了一下整理如下(經過驗證):
static Logger logger = Logger.getLogger(MD5Builder.class);
// 用來將字節轉換成 16 進製表示的字符
static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 對文件全文生成MD5摘要
* @param file 要加密的文件
* @return MD5摘要碼
*/
public static String getMD5(File file) {
FileInputStream fis = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
logger.info("MD5摘要長度:" + md.getDigestLength());
fis = new FileInputStream(file);
byte[] buffer = new byte[2048];
int length = -1;
logger.info("開始生成摘要");
long s = System.currentTimeMillis();
while ((length = fis.read(buffer)) != -1) {
md.update(buffer, 0, length);
}
logger.info("摘要生成成功,總用時: "
+ (System.currentTimeMillis() - s) + "ms");
byte[] b = md.digest();
return byteToHexString(b);
// 16位加密
// return buf.toString().substring(8, 24);
} catch (Exception ex) {
logger.error(ex);
ex.printStackTrace();
return null;
}finally {
try {
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* 對一段String生成MD5加密信息
* @param message 要加密的String
* @return 生成的MD5信息
*/
public static String getMD5(String message){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
logger.info("MD5摘要長度:" + md.getDigestLength());
byte[] b = md.digest(message.getBytes());
return byteToHexString(b);
} catch (NoSuchAlgorithmException e) {
logger.error(e);
e.printStackTrace();
return null;
}
}
/**
* 把byte[]數組轉換成十六進制字符串表示形式
* @param tmp 要轉換的byte[]
* @return 十六進制字符串表示形式
*/
private static String byteToHexString(byte[] tmp) {
String s;
// 用字節表示就是 16 個字節
char str[] = new char[16 * 2]; // 每個字節用 16 進製表示的話,使用兩個字符,
// 所以表示成 16 進制需要 32 個字符
int k = 0; // 表示轉換結果中對應的字符位置
for (int i = 0; i < 16; i++) { // 從第一個字節開始,對 MD5 的每一個字節
// 轉換成 16 進制字符的轉換
byte byte0 = tmp[i]; // 取第 i 個字節
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字節中高 4 位的數字轉換,
// >>> 爲邏輯右移,將符號位一起右移
str[k++] = hexDigits[byte0 & 0xf]; // 取字節中低 4 位的數字轉換
}
s = new String(str); // 換後的結果轉換爲字符串
return s;
}
}