安全散列算法(英語:Secure Hash Algorithm,縮寫爲SHA)是一個密碼散列函數家族,是FIPS所認證的安全散列算法。能計算出一個數字消息所對應到的,長度固定的字符串(又稱消息摘要)的算法。且若輸入的消息不一樣,它們對應到不一樣字符串的機率很高。java
SHA家族的五個算法,分別是SHA-1、SHA-22四、SHA-25六、SHA-384,和SHA-512,由美國國家安全局(NSA)所設計,並由美國國家標準與技術研究院(NIST)發佈;是美國的政府標準。後四者有時並稱爲SHA-2。SHA-1在許多安全協定中廣爲使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被視爲是MD5(更早以前被廣爲使用的雜湊函數)的後繼者。但SHA-1的安全性現在被密碼學家嚴重質疑;雖然至今還沒有出現對SHA-2有效的攻擊,它的算法跟SHA-1基本上仍然類似;所以有些人開始發展其餘替代的雜湊算法。 [1]算法
Initialize variables: h0 := 0x67452301 h1 := 0xEFCDAB89 h2 := 0x98BADCFE h3 := 0x10325476 h4 := 0xC3D2E1F0 Pre-processing: append the bit '1' to the message append k bits '0', where k is the minimum number >= 0 such that the resulting message length (in bits) is congruent to 448 (mod 512) append length of message (before pre-processing), in bits, as 64-bit big-endian integer Process the message in successive 512-bit chunks: break message into 512-bit chunks for each chunk break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 Extend the sixteen 32-bit words into eighty 32-bit words: for i from 16 to 79 w[i] := (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1 Initialize hash value for this chunk: a := h0 b := h1 c := h2 d := h3 e := h4 Main loop: for i from 0 to 79 if 0 ≤ i ≤ 19 then f := (b and c) or ((not b) and d) k := 0x5A827999 else if 20 ≤ i ≤ 39 f := b xor c xor d k := 0x6ED9EBA1 else if 40 ≤ i ≤ 59 f := (b and c) or (b and d) or (c and d) k := 0x8F1BBCDC else if 60 ≤ i ≤ 79 f := b xor c xor d k := 0xCA62C1D6 temp := (a leftrotate 5) + f + e + k + w[i] e := d d := c c := b leftrotate 30 b := a a := temp Add this chunk's hash to result so far: h0 := h0 + a h1 := h1 + b h2 := h2 + c h3 := h3 + d h4 := h4 + e Produce the final hash value (big-endian): digest = hash = h0 append h1 append h2 append h3 append h4
散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫作散列函數,存放記錄的數組叫作散列表。
15 111 % 15數據庫
有一個公司,當有新的員工來報道時,要求將該員工的信息加入(id,性別,年齡,名字,住址..),當輸入該員工的id時,要求查找到該員工的 全部信息.數組
要求:
不使用數據庫,,速度越快越好=>哈希表(散列)
添加時,保證按照id從低到高插入 [課後思考:若是id不是從低到高插入,但要求各條鏈表還是從低到高,怎麼解決?]
使用鏈表來實現哈希表, 該鏈表不帶表頭[即: 鏈表的第一個結點就存放僱員信息]
思路分析並畫出示意圖
代碼實現[增刪改查(顯示全部員工,按id查詢)]安全
1 package cn.smallmartial.hashTable; 2 3 import java.util.HashMap; 4 import java.util.Scanner; 5 6 /** 7 * @Author smallmartial 8 * @Date 2019/6/13 9 * @Email smallmarital@qq.com 10 */ 11 public class HashTableDemo { 12 13 public static void main(String[] args) { 14 //建立hash表 15 HashTab hashTab = new HashTab(7); 16 17 //寫一個簡單的菜單 18 String key = ""; 19 Scanner scanner = new Scanner(System.in); 20 while(true) { 21 System.out.println("add: 添加僱員"); 22 System.out.println("list: 顯示僱員"); 23 System.out.println("find: 查找僱員"); 24 System.out.println("exit: 退出系統"); 25 26 key = scanner.next(); 27 switch (key) { 28 case "add": 29 System.out.println("輸入id"); 30 int id = scanner.nextInt(); 31 System.out.println("輸入名字"); 32 String name = scanner.next(); 33 //建立 僱員 34 Emp emp = new Emp(id, name); 35 hashTab.add(emp); 36 break; 37 case "list": 38 hashTab.list(); 39 break; 40 case "find": 41 System.out.println("請輸入要查找的id"); 42 id = scanner.nextInt(); 43 hashTab.findEmpById(id); 44 break; 45 case "exit": 46 scanner.close(); 47 System.exit(0); 48 default: 49 break; 50 } 51 } 52 } 53 } 54 //建立hashTab 55 class HashTab{ 56 private int size; 57 private EmpLinkedList[] empLinkedListArray; 58 59 public HashTab(int size) { 60 this.size = size; 61 empLinkedListArray = new EmpLinkedList[size]; 62 63 for (int i = 0; i < size; i++) { 64 empLinkedListArray[i] = new EmpLinkedList(); 65 } 66 67 } 68 69 //添加僱員 70 public void add(Emp emp){ 71 //根據員工ID 添加到哪條聯 72 int hashFun = hashFun(emp.id); 73 empLinkedListArray[hashFun].add(emp); 74 75 } 76 77 //遍歷鏈表 78 public void list(){ 79 for (int i = 0; i < size; i++) { 80 empLinkedListArray[i].list(i); 81 } 82 } 83 84 //根據輸入的id,查找僱員 85 public void findEmpById(int id) { 86 //使用散列函數肯定到哪條鏈表查找 87 int empLinkedListNO = hashFun(id); 88 Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id); 89 if(emp != null) {//找到 90 System.out.printf("在第%d條鏈表中找到 僱員 id = %d\n", (empLinkedListNO + 1), id); 91 }else{ 92 System.out.println("在哈希表中,沒有找到該僱員~"); 93 } 94 } 95 public int hashFun(int id){ 96 return id % size; 97 } 98 } 99 //表示僱員 100 class Emp { 101 public int id; 102 public String name; 103 public Emp next; 104 105 public Emp(int id, String name) { 106 this.id = id; 107 this.name = name; 108 } 109 } 110 //表示鏈表 111 class EmpLinkedList{ 112 private Emp head; 113 114 public void add(Emp emp){ 115 if (head == null){ 116 head = emp; 117 return; 118 } 119 120 Emp curEmp = head; 121 while (true){ 122 if (curEmp.next == null){ 123 break; 124 } 125 curEmp = curEmp.next; 126 } 127 curEmp.next = emp; 128 } 129 130 //遍歷 131 public void list(int no){ 132 if (head == null){ 133 System.out.println("第"+no+"前鏈表爲空"); 134 return; 135 } 136 System.out.print("第"+no+"鏈表信息爲:"); 137 Emp curEmp = head; 138 while (true){ 139 System.out.print(curEmp.id+"=>"+curEmp.name); 140 if (curEmp.next == null){ 141 break; 142 } 143 curEmp = curEmp.next; 144 } 145 System.out.println(); 146 } 147 148 //根據id查找僱員 149 //若是查找到,就返回Emp, 若是沒有找到,就返回null 150 public Emp findEmpById(int id) { 151 //判斷鏈表是否爲空 152 if(head == null) { 153 System.out.println("鏈表爲空"); 154 return null; 155 } 156 //輔助指針 157 Emp curEmp = head; 158 while(true) { 159 if(curEmp.id == id) {//找到 160 break;//這時curEmp就指向要查找的僱員 161 } 162 //退出 163 if(curEmp.next == null) {//說明遍歷當前鏈表沒有找到該僱員 164 curEmp = null; 165 break; 166 } 167 curEmp = curEmp.next;//之後 168 } 169 170 return curEmp; 171 } 172 }