簡單說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
一個優秀的Hash算法,將能實現:node
正向快速
:給定明文,快速計算出hash值。逆向困難
:給定hash值,很難逆推出明文。輸入敏感
:原始輸入信息修改一點消息,產生的hash值看起來應該都有很大不一樣。衝突避免
:很難找到2段不一樣的明文,使他們的hash值相同。//將任何長度的字符串,經過運算,散列成0-15整數 func HashCode(key string) int { var index int = 0 index = int(key[0]) for k := 0; k < len(key); k++ { //1103515245是個好數字,使經過hashCode散列出的0-15的數字的機率是相等的 index *= (1103515245 + int(key[k])) } index >>= 27 index &= 16 - 1 return index }
將v存到hash表中的步驟:算法
package main import ( "./HMap" "fmt" ) func main() { //每一個空間都存有一個鏈表頭 HMap.InitBuckets() HMap.AddKeyValue("a","hello world") HMap.AddKeyValue("abc","hello China") fmt.Println(HMap.GetValueByKey("a")) fmt.Println(HMap.GetValueByKey("abc")) }
package HMap import "../LNodes" //實現hashmap原理 //建立長度爲16的數組 var buckets = make([]*LNodes.Node,16) func InitBuckets() { for i:=0;i<16;i++{ buckets[i]= LNodes.CreateHead(LNodes.KValue{"head","node"}) } } //將任何長度的字符串,經過運算,散列成0-15整數 //經過hashCode散列出的0-15的數字的機率是相等的 func HashCode(key string) int { var index int = 0 index = int(key[0]) for k := 0; k < len(key); k++ { index *= (1103515245 + int(key[k])) } index >>= 27 index &= 16 - 1 return index } //先hashmap中保存鍵值對 func AddKeyValue(key string ,value string ) { //計算key散列的結果,數組下標 var nIndex = HashCode(key) //在數組中得到頭結點 var headNode = buckets[nIndex] //得到當前鏈表的尾節點 var tailNode = LNodes.TailNode(headNode) //添加節點 LNodes.AddNode(LNodes.KValue{key,value},tailNode) } //獲取鍵值對 func GetValueByKey(key string ) string { var nIndex = HashCode(key) var headNode = buckets[nIndex] //經過鏈表查詢對應key 的value var value = LNodes.FindValueByKey(key,headNode) return value }
package LNodes import "fmt" type KValue struct { Key string Value string } type Node struct { Data KValue NextNode *Node } //建立頭結點 func CreateHead(data KValue ) *Node { var head = &Node{data,nil } return head } //添加節點 func AddNode(data KValue ,node *Node) *Node { var newNode = &Node{data ,nil} node.NextNode = newNode return newNode } //節點的遍歷 func ShowNodes(head *Node) { node:= head for { if node.NextNode !=nil { fmt.Println(node.Data) node = node.NextNode }else { break } } fmt.Println(node.Data) } //得到當前鏈表的尾節點 func TailNode(head *Node) *Node { node :=head for { if node.NextNode == nil { return node } else { node = node.NextNode } } } func FindValueByKey(key string ,head *Node) string { node :=head for { if node.NextNode!=nil { if node.Data.Key == key { return node.Data.Value } node = node.NextNode }else { break } } return node.Data.Value }