Java數字摘要 MD5

cp5m 9年前發布 | 3K 次閱讀 Java

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**

  • 消息摘要是一種算法:無論原始數據多長,消息摘要的結果都是固定長度的;是一種不可逆的算法
  • 原始數據任意bit位的變化,都會導致消息摘要的結果有很大的不同,且根據結果推算出原始數據的概率極低。
  • 消息摘要可以看作原始數據的指紋,指紋不同則原始數據不同。
  • @author stone
  • @date 2014-03-11 15:55:48 */
    public class MD5 {
public static void main(String[] args) throws Exception {  
    encodeByMAC("中國oP……&*()…&802134…");  

    encodeByMd5("中國oP……&*()…&802134…");  

    md5File();  
}  

/** 
 * 使用MAC 算法的 消息摘要 
 * @param data 
 * @throws Exception 
 */  
public static void encodeByMAC(String data) throws Exception{  

// KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
// SecretKey key = keyGen.generateKey(); //這個每次生成的key不一樣, 此處不能使用

    PBEKeySpec keySpec = new PBEKeySpec("randomkey^(^&*^%$".toCharArray());  
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");  
    SecretKey key = keyFactory.generateSecret(keySpec);  

    /* 
     *  此類提供“消息驗證碼”(Message Authentication Code,MAC)算法的功能。 
     *  MAC 基于秘密密鑰提供一種方式來檢查在不可靠介質上進行傳輸或存儲的信息的完整性。 
     *  通常,消息驗證碼在共享秘密密鑰的兩個參與者之間使用,以驗證這兩者之間傳輸的信息。 
     *  基于加密哈希函數的 MAC 機制也叫作 HMAC。結合秘密共享密鑰, 
     *  HMAC 可以用于任何加密哈希函數(如 MD5 或 SHA-1) 
     */  
    Mac mac = Mac.getInstance("HmacMD5");  
    mac.init(key);  
    byte[] dest = mac.doFinal(data.getBytes());  
    System.out.println(dest.length);  
    System.out.println("MAC摘要:" + Arrays.toString(dest));  
}  

/** 
 * md5加密  使用消息摘要MessageDigest 處理 
 * @throws Exception  
 */  
public static String encodeByMd5(String str) throws Exception{  
    MessageDigest md5;  
    md5 = MessageDigest.getInstance("MD5");  

    md5.update(str.getBytes()); //先更新摘要  
    byte[] digest = md5.digest(); //再通過執行諸如填充之類的最終操作完成哈希計算。在調用此方法之后,摘要被重置。  

    /* 
     * 使用指定的 byte 數組對摘要進行最后更新,然后完成摘要計算。 
     * 也就是說,此方法首先調用 update(input), 
     * 向 update 方法傳遞 input 數組,然后調用 digest()。 
     */  

// byte[] digest = md5.digest(str.getBytes());

    String hex = toHex(digest);  
    System.out.println("MD5摘要:" + hex);  
    return hex;  
}  

/** 
 * 文件數據摘要 
 * @throws Exception 
 */  
public static void md5File() throws Exception {  
    MessageDigest messageDigest = MessageDigest.getInstance("MD5");  
    DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(new File("abc.txt")), messageDigest);  
    dos.write("中華人民……&())f*(214)admin*".getBytes());  
    dos.close();  
    byte[] digest = messageDigest.digest();  
    System.out.println("使用流寫文件,該文件的摘要為:" + toHex(digest));  


    DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("abc.txt")), messageDigest);  
    byte[] buf = new byte[100];  
    int len;  
    while ((len = dis.read(buf)) != -1) {  
        System.out.println("讀取到的數據為:" + new String(buf, 0, len));  
    }  
    dis.close();  
    byte[] digest2 = messageDigest.digest();  
    //當流讀取完畢,即將文件讀完了, 這時的摘要 才與 寫入時的 一樣  
    System.out.println("使用流讀文件,該文件的摘要為:" + toHex(digest2));  
}  

/** 
 * md5 摘要轉16進制 
 * @param digest 
 * @return 
 */  
private static String toHex(byte[] digest) {  
    StringBuilder sb = new StringBuilder();  
    int len = digest.length;  

    String out = null;  
    for (int i = 0; i < len; i++) {  

// out = Integer.toHexString(0xFF & digest[i] + 0xABCDEF); //加任意 salt
out = Integer.toHexString(0xFF & digest[i]);//原始方法
if (out.length() == 1) {
sb.append("0");//如果為1位 前面補個0
}
sb.append(out);
}
return sb.toString();
}

} </pre>

 本文由用戶 cp5m 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!