經過記錄的存儲位置和它的關鍵字之間創建一個肯定的對應關係 f 以及處理衝突的方法,使得每一個關鍵字和結構中一個惟一的存儲位置相對應。這樣對於關鍵字 K 根據對應關係 f ,就能夠找到存儲在 f(K) .稱這種對應關係f 爲 哈希函數,按照這種方法創建的表稱爲哈希表。html
經過記錄的存儲位置和它的關鍵字之間創建一個肯定的對應關係 f ,使得每一個關鍵字和結構中一個惟一的存儲位置相對應。這樣對於關鍵字 K 根據對應關係 f ,就能夠找到存儲在 f(K) .稱這種對應關係f 爲 哈希函數,按照這種方法創建的表稱爲哈希表。java
對不一樣的關鍵字可能獲得同一個存儲位置-哈希地址,即 key1 不等於 key2 ,可是 f(key1)=f(key2),這種現象稱爲衝突。
git
1.3.1 均勻哈希函數
算法
任何一個關鍵字被映射到地址集合中任何一個地址的機率都是均等的。能夠採用直接地址法。`f(K)=a.key+bapache
public class FileInputStreamextends InputStream
A FileInputStream
obtains input bytes from a file in a file system. What files are available depends on the host environment.api
FileInputStream
is meant for reading streams of raw bytes such as image data. For reading streams of characters, consider using FileReader
.數組
public int read(byte[] b) throws IOException
Reads up to b.length
bytes of data from this input stream into an array of bytes. This method blocks until some input is available.ide
Overrides:函數
read
in class InputStream
學習
Parameters:
b
- the buffer into which the data is read.
Returns:
the total number of bytes read into the buffer, or -1
if there is no more data because the end of the file has been reached.
Throws:
IOException
- if an I/O error occurs.
See Also:
package com.yuan.test; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.log4j.Logger; public class MD5builder { 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); /**** * Parameters: input - the array of bytes. offset - the offset * to start from in the array of bytes. len - the number of * bytes to use, starting at offset. * * */ } 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; } }
http://blog.csdn.net/magister_feng/article/details/8266540
MD5 (Message Digest Algorithm 5 信息—摘要算法5 ) 的一些體會
若咱們定義一個函數 ,原型爲:
String MD5 ( Information info)
其中Information 表示任意長度的信息,注意是任意長度的。
實現這個函數的最終要求:
一、對於不一樣的輸入信息,產生的返回值 結果不一樣 且必須惟一
二、該算法不可逆轉,也就是就算擁有 返回結果和算法細節,也不可能推導出輸入的初始信息。
下面是MD5算法對一些特定值產生的返回值:
md5 ("") = d41d8cd98f00b204e9800998ecf8427e
md5 ("a") = 0cc175b9c0f1b6a831c399e269772661
md5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
md5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
md5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
md5("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789")
=d174ab98d277d9f5a5611c2c9f419d9f md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a
對於第二個要求,就是說,給你 一個 32位的字符串d41d8cd98f00b204e9800998ecf8427e,若是不事先告訴你,那你一生都別想得出它的輸入信息是 一個空白字符。
1. 對一段信息(message)產生信息摘要(message-digest),以防止被篡改。好比,在unix下有不少軟件在下載的時候都有一個文件名相同,文件擴展名爲.md5的文件,在這個文件中一般只有一行文本,大體結構如:
md5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461
這就是tanajiya.tar.gz文件的數字簽名。md5將整個文件看成一個大文本信息,經過其不可逆的字符串變換算法,產生了這個惟一的md5信息摘要。若是在之後傳播這個文件的過程當中, 不管文件的內容發生了任何形式的改變(包括人爲修改或者下載過程當中線路不穩定引發的傳輸錯誤等),只要你對這個文件從新計算md5時就會發現信息摘要不相同,由此能夠肯定你獲得的只是一個不正確的文件。
2.防止抵賴。這須要有第三方權威機構的參與。A 寫了個文件,權威機構對改文件用MD5算法產生摘要信息作好記錄。若之後A說這文件不是我寫的,權威機構只需對改文件從新產生摘要信息跟記錄在冊的摘要信息進行比對,相同的話,就證實是A寫的了。這就是所謂的「數字簽名」了。
3. 加密信息。好比在unix系統中用戶的密碼就是以md5(或其它相似的算法)經加密後存儲在文件系統中。當用戶登陸的時候,系統把用戶輸入的密碼計算成md5值,而後再去和保存在文件系統中的md5值進行比較,進而肯定輸入的密碼是否正確。經過這樣的步驟,系統在並不知道用戶密碼的明碼的狀況下就能夠肯定用戶登陸系統的合法性。這不但能夠避免用戶的密碼被具備系統管理員權限的用戶知道,並且還在必定程度上增長了密碼被破解的難度。