MessageDigest 通過其getInstance系列靜態函數來進行實例化和初始化。MessageDigest 對象通過使用 update
方法處理數據。任何時候都可以調用 reset
方法重置摘要。一旦所有需要更新的數據都已經被更新了,應該調用 digest
方法之一完成哈希計算并返回結果。
對于給定數量的更新數據,digest
方法只能被調用一次。digest
方法被調用后,MessageDigest 對象被重新設置成其初始狀態。
MessageDigest 的實現可隨意選擇是否實現 Cloneable 接口。客戶端應用程可以通過嘗試復制和捕獲 CloneNotSupportedException 測試可復制性:
MessageDigest md = MessageDigest.getInstance("SHA");
try {
md.update(toChapter1);
MessageDigest tc1 = md.clone();
byte[] toChapter1Digest = tc1.digest();
md.update(toChapter2);
...etc.
} catch (CloneNotSupportedException cnse) {
throw new DigestException("couldn't make digest of partial content");
}
注意1:即時給定MessageDigest的實現是不可復制的,則仍然能夠通過getInstance方法實例化幾個實例計算來同時進行摘要信息的計算。
注意2:由于歷史原因,此類是抽象的,是從
MessageDigestSpi
擴展的。應用程序開發人員只應該注意在此MessageDigest
類中定義的方法;超類中的所有方法是供希望提供自己的信息摘要算法實現的加密服務提供者使用的。注意3:MessageDigest并不是單實例的。如下代碼所示:
try
{
MessageDigest mdTemp1 = MessageDigest.getInstance("MD5");
MessageDigest mdTemp2= MessageDigest.getInstance("MD5");
MessageDigest mdTemp3= MessageDigest.getInstance("MD5");
System.out.PRintln("mdTemp1==mdTemp2?:"+(mdTemp1==mdTemp2));
System.out.println("mdTemp2==mdTemp3?:"+(mdTemp2==mdTemp3));
} catch (NoSuchAlgorithmException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
運行結果
mdTemp1==mdTemp2?:false
mdTemp2==mdTemp3?:false
構造方法摘要 | |
---|---|
protected | MessageDigest(String algorithm) 創建具有指定算法名稱的MessageDigest 實例對象。 |
方法摘要 | |
---|---|
Object | clone() 如果實現是可復制的,則返回一個副本。 |
byte[] | digest() 通過執行諸如填充之類的最終操作完成哈希計算。 |
byte[] | digest(byte[] input) 使用指定的字節數組對摘要進行最后更新,然后完成摘要計算。 |
int | digest(byte[] buf, int offset, int len) 通過執行諸如填充之類的最終操作完成哈希計算。 |
String | getAlgorithm() 返回標識算法的獨立于實現細節的字符串。 |
int | getDigestLength() 返回以字節為單位的摘要長度,如果提供程序不支持此操作并且實現是不可復制的,則返回 0。 |
static MessageDigest | getInstance(String algorithm) 生成實現指定摘要算法的 MessageDigest 對象。 |
static MessageDigest | getInstance(String algorithm, Provider provider) 生成實現指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。 |
static MessageDigest | getInstance(String algorithm, String provider) 生成實現指定提供程序提供的指定算法的 MessageDigest 對象,如果該算法可從指定的提供程序得到的話。 |
Provider | getProvider() 返回此信息摘要對象的提供程序。 |
static boolean | isEqual(byte[] digesta, byte[] digestb) 比較兩個摘要的相等性。 |
void | reset() 重置摘要以供再次使用。 |
String | toString() 返回此信息摘要對象的字符串表示形式。 |
void | update(byte input) 使用指定的字節更新摘要。 |
void | update(byte[] input) 使用指定的字節數組更新摘要。 |
void | update(byte[] input, int offset, int len) 使用指定的字節數組,從指定的偏移量開始更新摘要。 |
void | update(ByteBuffer input) 使用指定的 ByteBuffer 更新摘要。 |
public static MessageDigest getInstance(String algorithm)
注意:算法名不區分大小寫。例如,以下所有調用都是相等的:MessageDigest.getInstance("SHA");MessageDigest.getInstance("sha");MessageDigest.getInstance("sHa");調用程序可選擇指定提供者名稱,以保證所要求的算法是由已命名提供者實現的:public static MessageDigest getInstance(String algorithm, String provider);
調用 getInstance 將返回已初始化過的MessageDigest對象。因此,它不需要進一步的初始化。2.2、向MessageDigest傳送要計算的數據計算數據的摘要的第二步是向已初始化的MessageDigest對象提供傳送要計算的數據。這將通過一次或多次調用以下某個 update(更新)方法來完成:public void update(byte input);public void update(byte[] input);public void update(byte[] input, int offset, int len);2.3、計算摘要通過調用 update 方法向MessageDigest對象提傳送要計算的數據后,你就可以調用以下某個 digest(摘要)方法來計算摘要(即生成散列碼):public byte[] digest();public byte[] digest(byte[] input);public int digest(byte[] buf, int offset, int len);前兩個方法返回計算出的摘要。后一個方法把計算出的摘要儲存在所提供的 buf 緩沖區中,起點是 offset。len 是 buf 中分配給該摘要的字節數。該方法返回實際存儲在 buf 中的字節數。對第二個接受輸入字節數組變量的 digest 方法的調用等價于用指定的輸入調用:public void update(byte[] input)
,接著調用不帶參數的 digest 方法.三、例子演示3.1、★ 編程思路:java.security包中的MessageDigest類提供了計算消息摘要(即生成散列碼)的方法,首先生成對象,執行其update( )方法可以將原始數據傳遞給該對象,然后執行其digest( )方法即可得到消息摘要。具體步驟如下:(1)生成MessageDigest對象MessageDigest m=MessageDigest.getInstance("MD5");
MessageDigest類也是一個工廠類,其構造器是受保護的,不允許直接使用new MessageDigist( )來創建對象,而必須通過其靜態方法getInstance( )生成MessageDigest對象。其中傳入的參數指定計算消息摘要所使用的算法,常用的有"MD5","SHA"等。(2)傳入需要計算的字符串m.update(x.getBytes("UTF8" ));
分析:x為需要計算的字符串,update傳入的參數是字節類型或字節類型數組,對于字符串,需要先使用getBytes( )方法生成字符串數組。(3)計算消息摘要byte s[ ]=m.digest( );
分析:執行MessageDigest對象的digest( )方法完成計算,計算的結果通過字節類型的數組返回。(4)處理計算結果必要的話可以使用如下代碼將計算結果(byte數組)轉換為字符串。static String convertToHexString(byte data[]) { StringBuffer strBuffer = new StringBuffer(); for (int i = 0; i < data.length; i++) { strBuffer.append(Integer.toHexString(0xff & data[i])); } return strBuffer.toString(); }3.2、示例一★完整程序如下:public class MessageDigestDemo extends Thread { public void run() { String text = "abc"; byte data[] = null; MessageDigest m; try { data = text.getBytes("UTF8"); m = MessageDigest.getInstance("MD5"); m.update(data); byte resultData[] = m.digest(); System.out.println(convertToHexString(resultData)); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } static String convertToHexString(byte data[]) { StringBuffer strBuffer = new StringBuffer(); for (int i = 0; i < data.length; i++) { strBuffer.append(Integer.toHexString(0xff & data[i])); } return strBuffer.toString(); }}★運行結果900150983cd24fb0d6963f7d28e17f72
3.3、示例二在這里我們將對計算生成的md5使用 sun.misc.BASE64Encoder進行簡單的加密。public String md5sumWithEncoder(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException{ /*確定計算方法*/ MessageDigest md5=MessageDigest.getInstance("MD5"); BASE64Encoder base64en = new BASE64Encoder(); /*加密后的散列碼字符串*/ String strMd5=base64en.encode(md5.digest(text.getBytes("utf-8"))); return strMd5; }調用函數String str="0123456789" System.out.println(md5sumWithEncoder(str)); 輸出eB5eJF1ptWaXm4bijspyxw==
新聞熱點
疑難解答