希函数定义

哈希函数(英語:Hash function)又称散列函数散列函数摘要算法、单向散列函数散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个(哈希函数返回的值)称为指纹、哈希值哈希代码摘要散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。[1]好的散列函数在输入域中很少出现散列冲突

完美哈希函数 就是指没有冲突的哈希函数。

如今,散列算法也被用来加密存在数据库中的密码(password)字符串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码。

使用哈希函数为哈希表编制索引称为哈希分散存储寻址

哈希函数的特性

  • 单向散列函数(one-wayhash function),也就是通俗叫的哈希函数
  • 第一个特点:输入可以任意长度,输出是固定长度
  • 第二个特点:计算hash值的速度比较快
  • 第三个特点,冲突特性(Collision resistance):找出任意两个不同的输入值 x、y,使得 H (x)= H (y)是困难的。(这里称为「困难」的原因,是消息空间是无穷的,而哈希值空间是有限的,因此一定会存在碰撞,只是对寻找碰撞的算力需要有难度上的约束以哈希函数 SHAI (输出为 160-bit)为例:其输出空间为(0,2^160),假设输出范围一万亿个哈希值,发生碰撞的概率仅为 3×10-25。被碰撞的概率太低,几乎不可能。
  • 第四个特点:隐藏性(Hiding)或者叫做单向性(one-way):哈希函数的单向性意味着,给定一个哈希值,我们无法(很难)逆向计算出其原像输入。
  • 第五点:谜题友好(puzzlefriendly)

HashTable

定义

哈希表时保存数据的表。通过哈希函数使得数据和存储位置之间建立一一对应的映射关系。在查找时,通过哈希函数可以直接找到该元素。

HashTable负载因子

负载因子 = 填入表中的元素个数 / 哈希表的长度

负载因子是哈希表装满的标志因子,由于表长是定值,负载因子与填入标志元素的个数成正比,所以负载因子越大,填入表中的元素个数越多,产生冲突的可能性越大,反之,负载因子越小,填入表中的元素个数越少,产生冲突的可能性越小。
        对于闭散列,负载因子是一个很重要的因素,因该严格控制在07~0.8左右。超过0.8,CPU缓存命中率降低。所以,在闭散列中,一般负载因子超过0.7就会进行扩容处理。
为什么在散列表中不在负载因子等于1时扩容?
        因为当哈希表快满了的时候,插入数据,冲突的概率很大,然后需要查找插入位置。会导致效率降低。

HashTable中避免哈希函数冲突的方法

哈希函数的目标是尽量减少冲突,但实际应用中冲突是无法避免的,所以在HashTable 中哈希函数冲突发生时,必须有相应的解决方案。而发生冲突的可能性又跟以下两个因素有关:

(1)       装填因子α(用于判断何时扩容hashtable .net core 是0.72 java是0.75):所谓装填因子是指合希表中已存入的记录数n与哈希地址空间大小m的比值,即 α=n / m ,α越小,冲突发生的可能性就越小;α越大(最大可取1),冲突发生的可能性就越大。这很容易理解,因为α越小,哈希表中空闲单元的比例就越大,所以待插入记录同已插入的记录发生冲突的可能性就越小;反之,α越大,哈希表中空闲单元的比例就越小,所以待插入记录同已插入记录冲突的可能性就越大;另一方面,α越小,存储窨的利用率就越低;反之,存储窨的利用率就越高。为了既兼顾减少冲突的发生,又兼顾提高存储空间的利用率,通常把α控制在0.6~0.9的范围之内,C#的HashTable类把α的最大值定为0.72。

(2)       与所采用的哈希函数有关。若哈希函数选择得当,就可使哈希地址尽可能均匀地分布在哈希地址空间上,从而减少冲突的发生;否则,就可能使哈希地址集中于某些区域,从而加大冲突发生的可能性。

HashTable中哈希函数冲突解决方法

冲突解决技术可分为两大类:开散列法(又称为链地址法)和闭散列法(又称为开放地址法)。哈希表是用数组实现的一片连续的地址空间,两种冲突解决技术的区别在于发生冲突的元素是存储在这片数组的空间之外还是空间之内:

(1)       开散列法也叫链地址法、拉链法(JAVA采用这种方式)发生冲突的元素存储于数组空间之外。可以把“开”字理解为需要另外“开辟”空间存储发生冲突的元素。

开散列又叫链地址法(开链法),哈希表中的数组是一个指针数组。数据是以链表的形式保存,数组的元素指向链表的头节点。

        首先,数据通过哈希函数计算出保存位置,计算出来相同位置的数据归于同一个集合中,每一个子集和称为一个桶,每一个桶中的元素通过链表连接起来,链表的头结点保存在哈希表中。

        将哈希冲突的数据一链表的方式保存在一个位置。不会占用其它数据的位置。

 开散列增容:

        开散列增容看的也是负载因子。
        桶的数量是一定的,因为数组的数量一定。随着元素的不断插入,桶中元素的数量会不断增多,极端情况下,可能会导致一个桶中数量链表结点非常多,在查找元素时,会影响哈希表的效率。
        因此在一定情况下要对哈希表进行增容。该条件怎么确认呢?最好的情况下,是每一个桶正好一个结点,在插入数据会发生哈希冲突,。
        因当插入元素个数正好等于桶的个数时,即负载因子等于1时,可以给哈希表增容。
        增容时,会按照哈希函数重新改变位置,减少冲突。

(2)       闭散列法/开放定址法(.net core 采用这种方式)发生冲突的元素存储于数组空间之内。可以把“闭”字理解为所有元素,不管是否有冲突,都“关闭”于数组之中。闭散列法又称开放地址法,意指数组空间对所有元素,不管是否冲突都是开放的。

线性探测

 插入
    通过哈希函数获取插入位置
    如果该位置没有元素,直接插入新元素。如果有元素,发生哈希冲突,在冲突位置顺序往后找下一个空位置,插入新元素。

删除

        通过线性探测插入元素,我们知道哈希冲突的元素,一定会保存在保存位置的连续且不为空的位置,意思就是找哈希冲突的数据时,往哈希冲突位置往后找到为空位置截至。所以删除数据时,不能随便删除数据。如下:

因此线性探测采用标记的伪删除来删除一个元素,就是哈希表中保存的是一个结构体,结构以里有一个变量保存数据,一个变量了代表当前位置的状态。

//状态
enum State{
EXIT,//存在元素
DELETE,//该位置为删除状态
EMPTY,//该位置为空,不存在元素
};
//保存的元素类型
struct Ele{
T _data;//数据
State _state = EMPTY;//状态
};
【来源:https://python.iitter.com/other/68944.html,转载请注明】

线性探测缺点:一旦发生哈希冲突,所有冲突的数据都会连在一起保存,容易产生数据堆积,此时插入一数据时,可能一段位置全被占用了,一直要找空位置,导致效率降低。

二次探测

针对线性探测导致冲突数据堆积的缺点,二次探测找空位置的方法是:

Hi = (H0 + i * i) % capacity,H0是一开始数据保存的位置,也就是冲突位置,Hi查找的空位置。这样查找可以使得冲突数据位置的错开的。

哈希函数算法「家族」

从哈希(Hash)函数这一概念诞生至今,已经提出了几十种哈希算法

,每类算法对应不同的参数又会形成不同的算法实现。众多的哈希函数如同一个江湖,其中 MD 家族和 SHA 家族是「哈希江湖」中最具声望的两大家族。

国际: MD4、MD5、SHA-1、SHA-256、SHA-3。(MD 系列、SHA-1 已被破解)

国内:国产自主研发的商用密码哈希算法,即 SM3。

【C# 集合】Hash哈希函数 |散列函数|摘要算法的更多相关文章

  1. Java集合(八)哈希表及哈希函数的实现方式

    Java集合(八)哈希表及哈希函数的实现方式 一.哈希表 非哈希表的特点:关键字在表中的位置和它之间不存在一个确定的关系,查找的过程为给定值一次和各个关键字进行比较,查找的效率取决于和给定值进行比较的 ...

  2. 字符串哈希函数(String Hash Functions)

    哈希函数举例 http://www.cse.yorku.ca/~oz/hash.html Node.js使用的哈希函数 https://www.npmjs.org/package/string-has ...

  3. python hash 哈希值

    自增知识点 1,哈希 什么是可哈希(hashable)? 简要的说可哈希的数据类型,即不可变的数据结构(字符串str.元组tuple.对象集objects). 哈希有啥作用? 它是一个将大体量数据转化 ...

  4. 左神算法第五节课:认识哈希函数和哈希表,设计RandomPool结构,布隆过滤器,一致性哈希,岛问题,并查集结构

    认识哈希函数和哈希表 MD5Hash值的返回范围:0~9+a~f,是16位,故范围是0~16^16(2^64)-1, [Hash函数],又叫散列函数: Hash的性质: 1)  输入域无穷大: 2)  ...

  5. Hash哈希(一)

    Hash哈希(一) 哈希是大家比较常见一个词语,在编程中也经常用到,但是大多数人都是知其然而不知其所以然,再加上这几天想写一个一致性哈希算法,突然想想对哈希也不是很清楚,所以,抽点时间总结下Hash知 ...

  6. Python 字典和集合基于哈希表实现

    哈希表作为基础数据结构我不多说,有兴趣的可以百度,或者等我出一篇博客来细谈哈希表.我这里就简单讲讲:哈希表不过就是一个定长数组,元素找位置,遇到哈希冲突则利用 hash 算法解决找另一个位置,如果数组 ...

  7. 算法初级面试题05——哈希函数/表、生成多个哈希函数、哈希扩容、利用哈希分流找出大文件的重复内容、设计RandomPool结构、布隆过滤器、一致性哈希、并查集、岛问题

    今天主要讨论:哈希函数.哈希表.布隆过滤器.一致性哈希.并查集的介绍和应用. 题目一 认识哈希函数和哈希表 1.输入无限大 2.输出有限的S集合 3.输入什么就输出什么 4.会发生哈希碰撞 5.会均匀 ...

  8. 第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型

    第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型 Hash操作,redis中Hash在内存中的存储格式如下图: hset(name, key, value)name ...

  9. hash 哈希查找复杂度为什么这么低?

    hash 哈希查找复杂度为什么这么低? (2017-06-23 21:20:36) 转载▼   分类: c from: 作者:jillzhang 出处:http://jillzhang.cnblogs ...

随机推荐

  1. http状态码 200 304 404 503等

    浏览器采用http请求时,会封装http get等信息见下图请求头,然后服务器响应后回发一些信息,包括状态码,响应头,响应信息等等,如下图. 右上图可见两种状态码,一种是200 一种是304.其中20 ...

  2. 学习JAVAWEB第三天

    ## 数据库的设计· 1. 多表之间的关系 1. 分类: 1. 一对一(了解): * 如:人和身份证 * 分析:一个人只有一个身份证,一个身份证只能对应一个人 2. 一对多(多对一): * 如:部门和 ...

  3. HCNP Routing&Switching之组播技术-IGMP-Snooping

    前文我们了解了组播协议IGMP相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15700550.html:今天我们来聊一聊二层交换机处理组播报文所面临的 ...

  4. PyTorch 1.4 中文文档校对活动正式启动 | ApacheCN

    一如既往,PyTorch 1.4 中文文档校对活动启动了! 认领须知 请您勇敢地去翻译和改进翻译.虽然我们追求卓越,但我们并不要求您做到十全十美,因此请不要担心因为翻译上犯错--在大部分情况下,我们的 ...

  5. JS 高阶函数

    笔记整理自:廖雪峰老师的JS教程 目录 概述 Array中的高阶函数 map(返回新的Array) reduce(返回新的Array) filter(返回新的Array) sort(返回同一Array ...

  6. Android WebView组件 访问部分网页崩溃问题【已解决】

    最近刚接触Android,在测试WebView组件时发现总是出现崩溃现像: 提示:ERR_CLEARTEXT_NOT_PERMITTED 当时以为是权限问题,查找自己的AndroidManifest文 ...

  7. Java内存分析简单介绍

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11904422.html Java内存分析简单介绍: 1. # 设置内存溢出时自动生成堆内存快照 ...

  8. .NET 6全文检索引擎Lucene.NET 4.8简单封装

    前言 因为最近在做一个检索数据的工具.最开始用的Mysql8自带的全文检索功能.但是发现这货数据量超过百万之后,检索速度直线下降. 于是想到Lucene.net.花了一晚上时间做了简单的封装.可以直接 ...

  9. Java用n种方法编写实现双色球随机摇号案例

    方法清单 规则 实现方式一 实现方式二 实现方式三 实现方式四 实现方法五 之前我用JavaScript编写过一个实现双色球随机摇号的案例, 点击此处查看,今天我再用Java语言来实现这一效果. 规则 ...

  10. 微服务与SpiringBoot

    微服务: 微服务是一种架构风格,一般说到微服务都会说"微服务架构",即一个系统的各个功能(如结账,用户等)独立出来,以及各个服务独立出来,每个模块是可独立替换.可独立升级的软件单元 ...