哈希 学习笔记

2023-11-12

Tips:Hash=哈希=散列

Tips:哈希经常与哈希函数指一个意思。本文中哈希与哈希函数不做特殊区分,默认就是一个意思。

什么是哈希

在记录的关键字与记录的存储地址之间建立的一种对应关系叫哈希函数。
哈希函数就是一种映射,是从关键字到存储地址的映射。
通常,包含哈希函数的算法的算法复杂度都假设为O(1),这就是为什么在哈希表中搜索数据的时间复杂度会被认为是”平均为O(1)的复杂度”.

哈希两个主要概念

  1. 哈希函数的设计
  2. 哈希碰撞的解决

哈希函数的性质

所有哈希函数都有如下一个基本特性:如果两个哈希值是不相同的(根据同一函数),那么这两个哈希值的原始输入也是不相同的。这个特性是哈希函数具有确定性的结果,具有这种性质的哈希函数称为单向哈希函数。但另一方面,哈希函数的输入和输出不是唯一对应关系的,如果两个哈希值相同,两个输入值很可能是相同的,但也可能不同,这种情况称为“哈希碰撞(collision)”,这通常是两个不同长度的输入值,刻意计算出相同的输出值。输入一些数据计算出哈希值,然后部分改变输入值,一个具有强混淆特性的哈希函数会产生一个完全不同的哈希值。

典型的哈希函数都有非常大的定义域,比如SHA-2最高接受(264-1)/8长度的字节字符串。同时哈希函数一定有着有限的值域,比如固定长度的比特串。在某些情况下,哈希函数可以设计成具有相同大小的定义域和值域间的单射。哈希函数必须具有不可逆性。

一个优秀的哈希函数,将能满足:

  • 正向快速:给定原文和 Hash 算法,在有限时间和有限资源内能计算得到 Hash 值;
  • 逆向困难:给定(若干)Hash 值,在有限时间内无法(基本不可能)逆推出原文;
  • 输入敏感:原始输入信息发生任何改变,新产生的 Hash 值都应该发生很大变化;
  • 碰撞避免:很难找到两段内容不同的明文,使得它们的 Hash 值一致(即发生碰撞)。

碰撞避免有时候又被称为“抗碰撞性”,可分为“弱抗碰撞性”和“强抗碰撞性”。给定原文前提下,无法找到与之碰撞的其它原文,则算法具有“弱抗碰撞性”;更一般地,如果无法找到任意两个可碰撞的原文,则称算法具有“强抗碰撞性”。

很多场景下,也往往要求算法对于任意长的输入内容,输出为定长的 Hash 结果。

哈希碰撞

在计算机科学中,碰撞冲突是指两个不同的元素具有相同的哈希值。即不同的输入却有相同的输出。当数据量足够多时,碰撞是不可避免的。

哈希碰撞产生的理论前提

  1. 输入长度无限大
  2. 但是输出是有限长度

这必然会导致碰撞

举个例子

一般来说一年365天。假设一个班级里有366个学生,那么至少有2位学生生日相同。这就产生了碰撞

但这并不意味着散列算法就不能用了,因为凡事都要考虑代价,买光所有彩票去中一次头奖是毫无意义的。现代散列算法所存在的理由就是,它的不可逆性能在较大概率上得到实现,也就是说,发现碰撞的概率很小,这种碰撞能被利用的概率更小。

随意找到一组碰撞是有可能的,只要穷举就可以。散列算法得到的指纹位数是有限的,比如MD5算法指纹字长为128位,意味着只要我们穷举21282128次,就肯定能得到一组碰撞——当然,这个时间代价是难以想象的,而更重要的是,仅仅找到一组碰撞并没有什么实际意义。

你也许已经听过MD5已经被破解的新闻——但事实上,即便是MD5这种已经过时的散列算法,也很难实现逆向运算。我们现在更多的还是依赖于海量字典来进行尝试,也就是通过已经知道的大量的文件——指纹对应关系,搜索某个指纹所对应的文件是否在数据库里存在。

处理哈希碰撞

本文主要介绍两种方法

  1. 链地址法
  2. 开放地址法

1、链地址法(Seperate Chaining)

数组长度为m,已有k1、k2两个元素

k3经过哈希函数计算,与k2的位置一样,这时候就产生了冲突。

采用链地址法来处理这种情况的话,就直接把k3加在k2后面,形成一个链表。

2、开放地址法

开放地址发的意思是,地址是对所有元素开放的,就算哈希后的地址不是这一个,也可以占用这一个位置。

常见的开放地址法又可分为

  1. 线性探测法
  2. 平方探测法
  3. 再哈希法

为了方便演示,我们把哈希函数设置成简单的 hash(x) = x % 10

2、1线性探测法

我们输入11,25进行运算

11 % 10 = 1
25 % 10 = 5

那么11就插入下标为1的地址中,25就插入下标5的地址中

再插入数字31

31 % 10 = 1

这时候31和11的地址冲突了,怎么办?

31经过哈希函数运算,结果为1,。但是1被占用了,如果采用线性探测法,就在地址1的基础上+1,直到找到下一个空白的地址,然后插入。

小结

  • 开放地址法:每一个地址都对所有元素时开放的
  • 线性探测法:遇到哈希冲突,地址+1,直到找到空白地址,然后插入

这种效果效率低,每次+1的话,很容易会把某一个断区域的地址完全被占用,如果一段区域全部被占用了。那么每次都要+1很多次,计算次数会增加很多,浪费计算资源。

所以为了避免这种情况。诞生出了很多改进方法。比如平方探测法,不是每次都+1了,而是+平方,+1,+4,+9…+n^2,就是为了避免以整块区域完全被占据的情况。所以性能会提高一些。还有二次哈希法,就是遇到冲突时当前key通过另一个哈希函数在进行一次运算,然后地址加上这次哈希的结果,也就是+hash2(key)。

Tips:在JDK1.8之前,Java中的HashMap处理哈希冲突就是用链地址法,但1.8之后改进了这个方法,先使用链表,如果冲突到达了一定的数量,就改用红黑树。

哈希的应用

哈希算法广泛应用于很多场景,例如安全加密和数据结构中哈希表的查找,布隆过滤器和负载均衡(一致性哈希)等等。

  1. 数据结构:比如Java中的HashMap。
  2. 加密或验证:MD5和SHA加密算法
  3. 布隆过滤器:用于查找元素,空间和时间效率都很高。
  4. 一致性哈希

本文主要介绍三种应用

  1. 布隆过滤器
  2. 常见加密算法:MD5,SHA
  3. 哈希在java中的应用

1、布隆过滤器

布隆过滤器(Bloom Filter)是1970年由布隆提出的,它实际上是由一个很长的二进制向量和一系列随意映射函数组成。

 它是一种基于概率的数据结构,主要用来判断某个元素是否在集合内,它具有运行速度快(时间效率),占用内存小的优点(空间效率),但是有一定的误识别率和删除困难的问题。它能够告诉你某个元素一定不在集合内或可能在集合内。

在计算机科学中,我们常常会碰到时间换空间或者空间换时间的情况,通常两者不可兼得,我们要在两者之间取舍。但是布隆过滤器在空间与时间效率上都很高。

关于布隆过滤器,详细请看我另一篇博文https://blog.csdn.net/CrankZ/article/details/84928562

2、常见哈希算法

2、1MD5

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一,主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

MD5一度被广泛应用于安全领域。但是在2004年王小云教授公布了MD5、MD4、HAVAL-128、RIPEMD-128几个 Hash函数的碰撞。这是近年来密码学领域最具实质性的研究进展。使用他们的技术,在数个小时内就可以找到MD5碰撞。使本算法不再适合当前的安全环境。目前,MD5计算广泛应用于错误检查。例如在一些BitTorrent下载中,软件通过计算MD5和检验下载到的碎片的完整性。

2、2SHA家族

SHA家族算法的种类很多,有SHA0、SHA1、SHA256、SHA384等等,它们的计算方式和计算速度都有差别。其中SHA1是现在用途最广泛的一种算法。包括GitHub在内的众多版本控制工具以及各种云同步服务都是用SHA1来区别文件,很多安全证书或是签名也使用SHA1来保证唯一性。长期以来,人们都认为SHA1是十分安全的,至少大家还没有找到一次碰撞案例。

但这一事实在2017年2月破灭了。CWI和Google的研究人员们成功找到了一例SHA1碰撞,而且很厉害的是,发生碰撞的是两个真实的、可阅读的PDF文件。这两个PDF文件内容不相同,但SHA1值完全一样。(对于这件事的影响范围及讨论,可参考知乎上的讨论:如何评价 2 月 23 日谷歌宣布实现了 SHA-1 碰撞?)

所以,对于一些大的商业机构来说, MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。

2、3Java使用MD5,SHA1

public static void main(String[] args) {
    System.out.println(encrypt("CrankZ", "MD5"));
    System.out.println(encrypt("CrankZ", "SHA1"));
}

public static String encrypt(String str, String algorithm) {
    // 计算md5函数
    try {
        // 生成一个MD5加密计算摘要
        MessageDigest md = MessageDigest.getInstance(algorithm);
        md.update(str.getBytes());
        // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
        // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
        return new BigInteger(1, md.digest()).toString(16);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

3、Hash在Java中的应用

  1. Object.hashCode()
  2. HashMap

参考:

维基百科
https://blog.csdn.net/asdzheng/article/details/70226007
http://www.alloyteam.com/2017/05/hash-functions-introduction/
https://coding.imooc.com/class/207.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哈希 学习笔记 的相关文章

  • 50个c/c++源代码网站

    C C 是最主要的编程语言 这里列出了50名优秀网站和网页清单 这些网站提供c c 源代码 这份清单提供了源代码的链接以及它们的小说明 我已尽力包括最佳的C C 源代码的网站 这不是一个完整的清单 您有建议可以联系我 我将欢迎您的建 议 以
  • Mysql 数据库

    数据库基础 1 什么是数据库 用来存储数据 数据库可在硬盘及内存中存储数据 数据库与文件存储数据的区别 数据库本质也是通过文件来存储数据 数据库的概念就是系统的管理存储数据的文件 数据库介绍 本质就是存储数据的C S架构的socket套接字
  • python 历险记(五)— python 中的模块

    目录 前言 基础 模块化程序设计 模块化有哪些好处 什么是 python 中的模块 引入模块有几种方式 模块的查找顺序 模块中包含执行语句的情况 用 dir 函数来窥探模块 python 的内置模块有哪些 结语 参考文档 系列文章列表 前言
  • 算法--将数组分成和相等的多个子数组,求子数组的最大个数

    作者 陈太汉 一个整数数组 长度为n 将其分为m份 使各份的和相等 求m的最大值 比如 3 2 4 3 6 可以分成 3 2 4 3 6 m 1 3 6 2 4 3 m 2 3 3 2 4 6 m 3 所以m的最大值为3 算法 原理的思想是
  • BP神经网络与Python实现

    人工神经网络是一种经典的机器学习模型 随着深度学习的发展神经网络模型日益完善 联想大家熟悉的回归问题 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数 并使用该函数进行预测 网络的训练过程即为调节该函数参数提高预测精度的过程
  • 数据结构----链式栈

    目录 前言 链式栈 操作方式 1 存储结构 2 初始化 3 创建节点 4 判断是否满栈 5 判断是否空栈 6 入栈 7 出栈 8 获取栈顶元素 9 遍历栈 10 清空栈 完整代码 前言 前面我们学习过了数组栈的相关方法 链接 线性表 栈 栈
  • DNG格式解析

    Author Maddock Date 2015 04 22 转载请注明出处 http www cnblogs com adong7639 p 4446828 html DNG格式基本概念 DNG格式是在TIFF的基础上扩展出来的 要了解D
  • 递归算法中的时间复杂度分析

    对于一种算法的时间复杂度分析还是特别重要的 在一些非递归算法中 我们仅仅看运算次数最多的那一行代码可能执行多少次就可以 实际就是看在循环中变量的变化 但是对于递归算法中该怎么分析呢 下面介绍几种递归函数中的算法时间复杂度分析的方法 0 递推
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • 『Python基础-15』递归函数 Recursion Function

    什么是递归函数 一种计算过程 如果其中每一步都要用到前一步或前几步的结果 称为递归的 用递归过程定义的函数 称为递归函数 例如连加 连乘及阶乘等 凡是递归的函数 都是可计算的 即能行的 递归就是一个函数在它的函数体内调用它自身 编程语言中的
  • UE4命令行使用,解释

    命令行在外部 从命令行运行编辑项目 1 导航到您的 LauncherInstall VersionNumber Engine Binaries Win64 目录中 2 右键单击上 UE4Editor exe 的可执行文件 并选择创建快捷方式
  • 链表面试题(一):反转链表的算法实现

    关于链表的考察 链表是面试里面经常涉及到的考点 因为链表的结构相比于Hashmap Hashtable Concurrenthashmap或者图等数据结构简单许多 对于后者更多面试的侧重点在于其底层实现 比如Hashmap中Entry
  • Unique Binary Search Trees -- LeetCode

    原题链接 http oj leetcode com problems unique binary search trees 这道题要求可行的二叉查找树的数量 其实二叉查找树可以任意取根 只要满足中序遍历有序的要求就可以 从处理子问题的角度来
  • 浮生六记

    浮生六记 目录 浮生六记卷一 闺房记乐 002 浮生六记卷二 闲情记趣 015 浮生六记卷三 坎坷记愁 022 浮生六记卷四 浪游记快 034 浮生六记 2 浮生六记卷一 闺房记乐 余生乾隆癸未冬十一月二十有二日 正值太平盛世 且在 衣冠之
  • 算法问题实战策略

    算法问题实战策略 基本信息作者 韩 具宗万 译者 崔盛一出版社 人民邮电出版社ISBN 9787115384621上架时间 2015 2 4出版日期 2015 年3月开本 16开页码 738版次 1 1 内容简介 算法问题实战策略 本书收录
  • CRC校验(二)

    CRC校验 二 参考 https blog csdn net liyuanbhu article details 7882789 https www cnblogs com esestt archive 2007 08 09 848856
  • 【数据结构入门精讲 | 第二篇】一文讲清算法复杂度

    上篇文章中我们引入了算法 数据结构 数据类型等概念 而要想衡量一个算法与数据结构是否为优质的 就需要一个衡量标准 这个衡量标准也是在我们实现一个好的算法时要遵循的原则 目录 基本概念 渐进性态 渐进性态数学表征 算法复杂度的运算 顺序搜索算
  • 按照层次遍历结果打印完全二叉树

    按照层次遍历结果打印完全二叉树 按照推论结果 l 层首个节点位置 2 h l 1 l 层节点间距 2 h l 1 1 编码实现 public static
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数
  • 高精度运算合集,加减乘除,快速幂,详细代码,OJ链接

    文章目录 零 前言 一 加法 高精度加法步骤 P1601 A B 二 减法 高精度减法步骤

随机推荐

  • arcgis for landsat 8处理

    landsat8的详细数据处理http vdisk weibo com s zrSeGYf9hMRAH http blog sina com cn s blog 764b1e9d01018z6j html http blog sina co
  • osgEarth的Rex引擎原理分析(五十五)Rex引擎如何给shader文件中的uniform变量赋值

    目标 五十四 中的问题128 有几个地方 RexEngine SDK vert glsl中的 uniform sampler2D oe tile elevationTex osgEarthDrivers engine rex RexTerr
  • 全桥逆变电路部分分析

    首先来看单相逆变不间断电源设计电路中的全桥逆变电路部分 它是由两个IR2101驱动和4个MOS管构成的全桥逆变电路 有人会说了 IR2101不是半桥驱动芯片吗 没错 的确是半桥驱动芯片 和IR2104一样的 常被用在三相逆变电路中做三个半桥
  • RCE漏洞详解及绕过总结(全面)

    作者 永不落的梦想 作者主页 传送 座右铭 过去属于死神 未来属于自己 本文专栏 Web漏洞篇 今日鸡汤 只有承担起旅途风雨 最终才能守得住彩虹满天 目录 一 rce漏洞概述 二 常见RCE漏洞函数 1 系统命令执行函数 2 代码执行函数
  • 华为OD机试真题-工作安排【2023Q1】【JAVA、Python、C++】

    题目描述 小明每周上班都会拿到自己的工作清单 工作清单内包含n项工作 每项工作都有对应的耗时时长 单位h 和报酬 工作的总报酬为所有已完成工作的报酬之和 那么请你帮小明安排一下工作 保证小明在指定的工作时间内工作收入最大化 输入描述 输入的
  • 手动安装xapk

    xpak文件实际是一个压缩包 用解压软件可查看其内容 情况1 obb 多见于游戏 apk主包文件很小 用户能安装并启动 要解锁游戏全部内容 则需要下载obb文件 obb文件一般位于 sd卡的根目录下 路径大概是 sdcard Android
  • vue admin-template 添加动态路由

    store getters js const getters sidebar state gt state app sidebar device state gt state app device token state gt state
  • MATLAB实现最大类间方差算法

    Otsu算法 大律法或最大类间方差法 最大类间方差法是由日本学者大津 Nobuyuki Otsu 于1979年提出的 是一种自适应的阈值确定的方法 又叫大津法 简称OTSU 它是按图像的灰度特性 将图像分成背景和目标2部分 背景和目标之间的
  • Pycharm破解方法

    3 破解补丁激活 优点 到期时间为2099年 基本为永久啦 缺点 相对服务器激活麻烦些 但是一共只需要3个步骤 其实并不麻烦 下载 https pan baidu com s 1mcQM8CLUnweY02ahKEr4PQ 并将 Jetbr
  • win7设置右键+T 快捷键 快速新建文本文档

    1 win r 组合键呼出 运行 win就是键盘上和桌面 开始 有相同图标的按键 田 字 2 输入regedit 回车 出现 注册表编辑器 窗口 3 窗口下寻找这个位置 HKEY CLASSES ROOT Local Settings Mu
  • 【pygame学习_5】窗口设计

    1 引言 窗体是游戏的交互界面 一般我们会遇到窗口大小可调 窗口无边框 全屏显示 最小化设计 改名字 换图标等设计需求 屏幕绘制有如下重要函数 2 屏幕模式函数 pygame display set mode print pygame di
  • java解析蓝奏云直连(解析真正文件地址)

    使用htmlunit解析蓝奏云直连 前言 最近有个需求 客户端需要更新软件版本 我一直在用蓝奏云 觉得是个非常不错的网盘 可是如果用户自己打开连接选择下载方式很麻烦 用过蓝奏的朋友都知道 打开外链还要选择普通下载 电信下载 联通下载 很麻烦
  • 多系统UEFI启动项清理,windows、ubuntu,win10盘符隐藏

    文章目录 step1 推荐方法 step2 在window系统中启动cmd窗口 win10 隐藏不必要的盘符 如单机多系统情形 step1 推荐方法 参考 https blog csdn net mtllyb article details
  • sap服务器数据库配置文件,安装和配置 SAP 和数据库

    安装和配置 SAP 和数据库 使用本节中的过程可以执行以下任务 安装 SAP 和数据库 安装 SAP 和可缩放的应用程序服务器 使 SAP 能够在群集中运行 检验 SAP 和数据库安装是否适合于中央实例 检验 SAP 和数据库安装是否适合于
  • R语言排序函数sort(),rank(),order()

    转载地址 http blog sina com cn s blog 6caea8bf0100spe9 html 在R中 和排序相关的函数主要有三个 sort rank order sort x 是对向量x进行排序 返回值排序后的数值向量 r
  • c++智能指针

    C 智能指针详解 本文系转载 原文出处 诚然原博主总结的非常好 我只是加一些自己觉得需要补充的地方 并且在最后给出目前c 11在智能指针这方面的弥补 一 简介 由于 C 语言没有自动内存回收机制 程序员每次 new 出来的内存都要手动 de
  • 分布式系统实现幂等性的方式

    幂等性 接口的幂等性就是同样的数据 在实现方法的多次调用 得到的结果一致 对于查询接口 天然的保持幂等性 但是对于cud来说 如何保持幂等性 看法 从以下方式来看 要保证幂等性 必须要有一个标识 至始至终的保持不变的标识 只有这样 后来的操
  • 开源点云数据集整理汇总

    目录 一 ModelNet40 1 网址 2 模型 二 ShapeNet 1 网址 2 模型 三 S3DIS Dataset 1 网址 2 模型 四 ScanNet 1 网址 2 模型 五 RGB D Object Dataset 1 网址
  • 麻雀算法极限学习机SSA-ELM回归预测及其MATLAB代码实现

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 更多Matlab仿真内容点击 智能优化算法 神经网络预测 雷达通信 无线传感器 信号处理 图像
  • 哈希 学习笔记

    Tips Hash 哈希 散列 Tips 哈希经常与哈希函数指一个意思 本文中哈希与哈希函数不做特殊区分 默认就是一个意思 什么是哈希 在记录的关键字与记录的存储地址之间建立的一种对应关系叫哈希函数 哈希函数就是一种映射 是从关键字到存储地