博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【go密码学】-Hash
阅读量:5875 次
发布时间:2019-06-19

本文共 2900 字,大约阅读时间需要 9 分钟。

Hash(散列函数)

简单说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

一个优秀的Hash算法,将能实现:

  • 正向快速:给定明文,快速计算出hash值。
  • 逆向困难:给定hash值,很难逆推出明文。
  • 输入敏感:原始输入信息修改一点消息,产生的hash值看起来应该都有很大不同。
  • 冲突避免:很难找到2段不同的明文,使他们的hash值相同。

典型的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}

hash表结构

图片描述

将v存到hash表中的步骤:

  • 通过HashCode计算v的HashCode值,从而确定存在在哪个hash链表下(0-15,共16个hash链).
  • 将v追加的hash链表的尾部.

go实现hash表

main.go

package mainimport (    "./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"))}

HMap.go

package HMapimport "../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}

LNode.go

package LNodesimport "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}

转载地址:http://uikix.baihongyu.com/

你可能感兴趣的文章
PHP 程序员的技术成长规划
查看>>
用于守护进程的出错处理函数
查看>>
AppCan可以视为Rexsee的存活版
查看>>
【转】SQL SERVER 2005 数据库状态为“可疑”的解决方法
查看>>
事件、委托、委托方法的总结(使用EventHandler<>)
查看>>
Revit API 创建带箭头的标注
查看>>
jetty启动报错Unsupported major.minor version 51.0
查看>>
Xamarin.Android开发实践(七)
查看>>
彩色图像上执行Mean Shift迭代搜索目标 ,维加权直方图 + 巴氏系数 + Mean Shift迭代...
查看>>
深入理解JavaScript系列
查看>>
strtol 函数用法
查看>>
eclipse内存溢出设置
查看>>
搭建jenkins环境(linux操作系统)
查看>>
VS 2015 GIT操作使用说明
查看>>
上海办理房产税变更
查看>>
每天一个linux命令(52):scp命令
查看>>
CMOS Sensor Interface(CSI)
查看>>
linq中的contains条件
查看>>
HDU 5590 ZYB's Biology 水题
查看>>
memcached 分布式聚类算法
查看>>