【基础算法】简单了解一下常见的几种散列算法?

2023-11-18

简单了解一下常见的几种散列算法?


如果觉得对你有帮助,能否点个赞或关个注,以示鼓励笔者呢?!博客目录 | 先点这里

  • 前提概念
    • 好的哈希函数
  • MD5 与 SHA
    • MD5
    • SHA 家族
  • CRC
  • MurmurHash
  • times31/33
    • times33
    • times31

前提概念


好的哈希函数

好的哈希函数

好的哈希函数应该具备如下几种特性

  • One-way 单向性
    输出确定,且无法逆推出源数据,即单向散列函数
  • Collision-resistant 抗冲突性
    产生两个相同散列值的概率低
  • Avalanche effect 雪崩效应
    原始数据的微小改动,会导致散列值巨大的差异

MD5 与 SHA


MD5

md5 摘要算法,又称 “MD5 Message-Digest Algorithm”, 是一种不可逆向的密码散列函数。

特性

  • 任意长度的原始数据,都将输出定长为 128 bit 的散列值
  • 属于加密散列函数,计算较为耗费 CPU 资源

SHA 家族

SHA 家族的加密算法,又称 “Secure Hash Algorithm”, 是一个密码散列函数家族,发布了多个版本的 SHA 加密函数,如 SHA-0,SHA-1,SHA-2,SHA-3 等

特性

  • 大部分仅支持 2^64 -1 的输入数据,根据不同的版本,有不同的位长,如 160,224,256,384,512 等,位数较长
    • sha-0,sha-1 输入不超过 2^64-1, 输出定长 160 bit

对比
  • MD5 和 SHA 通常都用在安全加密领域,因为都涉及数字加密,所以计算量都比较大,都比较消费 CPU 资源
    在这里插入图片描述

CRC


CRC 算法 ("Cyclic Redundancy Check") ,又称循环冗余校验算法,是一种常用于通信链路检错,判断数据是否损坏的散列函数,但也不局限于此,它的基本原理是利用除法与余数的原理来做为错误侦测的

我们进行通信时的网络信道并不总是可靠的。为了增加可靠性,我们需要在传输数据后加上一些冗余的码字。如果接收方能够通过它们直接纠正错误,那么我们就称之为纠错码(Error Correcting Code),而 CRC 就是一种优秀的检错码,因为 CRC 具有良好的雪崩效应,即单个 bit 发生改变,也会导致散列值发生较大的改变,所以得以在通讯领域广泛应用。

原理

  • 计算CRC的过程,就是用一个特殊的“除法”,来得到余数,这个余数就是CRC,而这里的除数则是一种 “模二除法”
  • 通讯传送中,发送方会在原始数据末尾加上 CRC 检错码,并与接收方约定好 “除数 (多项式)”,最会得到余数 (CRC 值),接收方就会以收到的原始数据除以约定好的除数,看看最终的结果是否与 CRC 检错码一致

在这里插入图片描述

比如发送发传输了一段二进制数据,并附上 CRC 校验码。接收方就可以根据所接收到的二进制数据的 CRC 散列值与接收到的 CRC 检错码进行比对,如果不一致,就代表接收的数据可能在通讯传输过程中有缺失或错误

特性

  • CRC 的协议有非常多种,比如 CCITT, MODBUS 等
  • CRC 根据多项式的不同也会产生不同长度的检错码 (散列值),比如 CRC-8,CRC-16,CRC-32,CRC-64, 分别对产生对应 8,16,32,64 位长度的检错码,具有一定的数据压缩映射能力

代码


MurmurHash


MurmurHash 是一种非加密型的散列函数,相比加密型散列函数,速度更快,差值最大可以达到几十倍,所以更适用于一般场景的哈希检索操作。MurmurHash 经历过多个版本的迭代,并有多种变种,当前最新版是 MurmurHash3。
且已被广泛应用在多种分布式系统中,比如 Redis, Kafka, Hbase, ElasticSearch

特性

  • MurmurHash2 可以产生 32/64 bit 范围的散列值,MurmurHash3 可以产生 32/128bit 范围的散列值
  • MurmurHash 支持加盐,即支持加一个种子值,而获得不同的 hash 规律,可以防止哈希洪水攻击(Hash-Flooding Attack

代码

    public static void main(String[] args) {
        HashFunction function = Hashing.murmur3_32();
        System.out.println(function.hashBytes("abcd".getBytes()).asInt());
        // output = 1139631978
    }
  • MurmurHash 的原理解析细节比较多,没看懂,就不贴了,这里是一个 Guava 提供的 murmur3 使用例子
  • murmur3 可以使用在一般的哈希值计算,比如短链系统等
  • redis-client-murmurhash
  • guava-murmurhash3

MurmurHash3_最详细的介绍


times31/33


times33

Times33 算法是一个简单的对 “字符串” 进行哈希的函数,又称 “DJB Hash Function” or “DJBX33A”

原理

  • 对字符串 s 进行逐个字符遍历,每次循环乘以 33,并加上 s[i] 字符的 ascii 码 , 然后求和即可
  • 乘数是33, hash 初始值为 5381

代码

    private static int times33(String s) {
        int hash = 5381;

        char[] val = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            hash = ((hash << 5) + hash) + val[i];
        }

        // hash is a positive integer,[0,2^31-1]
        hash &= Integer.MAX_VALUE;
        return hash;
    }
  • a * 33 = a * 2^5 + a = a * 32 + a
  • hash &= 0x7fffffff 是为了获得 0 或 正整数,因为 Java 的 int 是有符号整数,只能表示 [0, 2^31 -1] 的整数

why

  • 为什么取 33?
    • 并没有人给于一个比较充分的理由说明,不过通过对[1,256]数值的实验证明,偶数的哈希分布非常差,冲突较高,所以就剩下 128 个奇数,并不是 33 就是最佳的选项
    • 奇素数,哈希分布相比偶数更为良好
  • 初始值为什么是 5381?

times31

times31 其实是 Java String hashcode 函数所采用的算法,因其思想类似 times33, 但数值采用 31 ,所以被习惯性称之 times31

原理

  • 原理与 times33 一致,仅仅是乘数和初始值的选择不一样
  • 乘数是 31,初始值是 0

代码

    private static int times31(String s) {
        int hash = 0;

        char[] val = s.toCharArray();
        for (int i = 0; i < s.length(); i++) {
            hash = ((hash << 5) - hash) + val[i];
        }
        
        return hash;
    }
  • hash = ((hash << 5) - hash) + val[i] 等价于 hash = 31 * hash + val[i]
  • JDK 显式代码是 31 * hash, 是因为编译器会自行优化

why

  • 为什么取 31
    31 和 33 都是奇素数,理由其实跟 times33 差不多,都是实验数据中,采取比较好的奇素数

参考资料


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

【基础算法】简单了解一下常见的几种散列算法? 的相关文章

  • redis主从同步,总是显示master_link_status:down的解决方法

    前几天 在修改一台从节点的redis的监听端口后 重启了下redis 发现master link status 很长时间一直都是down状态 查看了redis日志 发现日志里出现很多的 I O error trying to sync wi
  • 计算机领域中随处可见的抽象

    想要管理多种具体的东西 那么需要遵守每种东西的规范 如果想要提供一种通用模式来对这些具体的东西统一管理 需要使用一种古老的技术 抽象 抽象是将多种具体的东西 管理时需要遵守的规范 的共同点抽取出来 放入到更高一层的抽象层 在抽象层不定义或少
  • 掉电无法启动数据库问题解决

    由于突然掉电 造成客户在windows平台上10 2 0 1数据库无法驱动 以下是具体解决步骤 一 定位故障问题 1 启动数据库 查看错误 SQL gt startup ora 01113 file 1 needs media recove
  • Linux网络安全-Zabbix入门(一)

    一 基本概念 1 监控目的 运行情况 提前发现问题 2 监控资源类别 公开 tcp udp 端口 私有 cpu 磁盘 监控一切需要监控的东西 只要能够想到 能够用命令实现的都能用来监控 如果想远程管理服务器就有远程管理卡 比如Dell id
  • RTX线程通信之——线程标志

    文章目录 Thread Flags 概念 RTX线程标志API 案例 LED灯同步闪亮 小结 参考资料 Thread Flags In a real application we need to be able to communicate
  • Linux 磁盘与文件系统管理(鸟哥私房菜)

    本文来自 http vbird dic ksu edu tw linux basic 0230filesystem php 第八章 Linux 磁盘与文件系统管理 系统管理员很重要的任务之一就是管理好自己的磁盘文件系统 每个分割槽不可太大也
  • win10 Enable developer Mode

    经过漫长的安装过程 win10终于装上了vs2015 rc 写个小程序试试 结果提示 根据提示打开 设置 更新 for developer 据说应该有这么个界面 但是这个界面根本出不来 直接闪退的说 翻 MSDN 终于翻出了解决方法 htt
  • CF、SF、OF、ZF标志位

    没学汇编 这种题我真是做一道错一道 OF overflow flag 溢出标志位 溢出标志位 OF 1 表示带符号整数运算时结果发生溢出 对于无符号整数运算 OF没有意义 对于有符号数的溢出判断方式有 1 采用一位符号位 思想为 或 则为溢
  • nslookup命令详解

    nslookup命令用于查询DNS的记录 查看域名解析是否正常 在网络故障的时候用来诊断网络问题 nslookup的用法相对来说还是蛮简单的 主要是下面的几个用法 1 直接查询 这个可能大家用到最多 查询一个域名的A记录 nslookup
  • 数据结构之哈希(C++实现)

    数据结构之哈希 C 1 哈希概念 顺序结构以及平衡树中 元素关键码与存储位置之间没有对应关系 因此在查找一个元素的时候 要经过关键码多次比较 顺序表查找的时间复杂度为O N 而平衡树中树的高度为O log 2 N 搜索的效率取决于搜索过程中
  • 通过源码包*.src.rpm定制开发rpm

    为什么80 的码农都做不了架构师 gt gt gt 1 基本流程 1 下载 安装相应的src rpm包 wget xxx src rpm rpm ivh xxx src rpm 这里的 安装 是指把xxx src rpm中的tar gz p
  • [架构之路-185]-《软考-系统分析师》-3-操作系统基本原理 - 文件索引表

    目录 一 文件的索引块 二 索引分配表 三 索引表的链接方案 四 多层索引 五 混合索引分配 一 文件的索引块 存放在目录中的文件 并非是文件的真实内容 目录中记录了文件的索引块是几号磁盘块 文件对应的索引表是存放在指定的磁盘块中的 二 索
  • Windows运行常用命令(win+R)

    1 calc 启动计算器 2 notepad 打开记事本 3 write 写字板 4 mspaint 画图板 5 snippingtool 截图工具 支持无规则截图 6 mplayer2 简易widnows media player 7 S
  • Linux常用命令记录

    文章目录 1 软件安装 安装软件 来自源服务器 安装 deb软件 来自本地 deb文件 修复依赖关系 卸载软件 2 文件 文件夹操作 删除文件夹 移动文件 文件重命名 3 程序查看 处理 进程查看 查看端口占用情况 强制终止程序 4 解压文
  • OS——文件管理系统磁盘的结构之搞清盘面和柱面

    如上图 每个柱面有三个盘面 即就是3个磁道 柱面可以抽象的理解成是一个套一个的立体的同心圆柱体 例 2019年408真题 磁盘有300个柱面 每个柱面有10个磁道 每个磁道有200个扇区 扇区大小为512B 则磁盘容量 分析 每个柱面有10
  • 由于回车符引起的shell错误

    今天弟弟写shell时出现一个错误 源代码如下 zip r 1 2 执行时出现错误 我也写了相同的语句 发现是可以执行的 把两个文件对比一看 差别在于 出错shell 正确shell 在linux下的回车是 n 在win下面的回车是 r n
  • 磁盘调度算法笔记和练习题

    磁盘调度算法 先来先服务FCFS 最短寻道时间优先SSTF 扫描调度SCAN 练习题 先来先服务FCFS 最短寻道时间优先SSTF 扫描调度SCAN 它是一次只响应一个方向上的请求 这个方向上的请求都响应完了 再掉头处理另一个方向上的 有点
  • CentOS Linux服务器安全设置

    转自 http www osyunwei com archives 754 html 引言 我们必须明白 最小的权限 最少的服务 最大的安全 所以 无论是配置任何服务器 我们都必须把不用的服务关闭 把系统权限设置到最小话 这样才能保证服务器
  • 《OSPF和IS-IS详解》一1.7 独立且平等

    本节书摘来自异步社区 OSPF和IS IS详解 一书中的第1章 第1 7节 作者 美 Jeff Doyle 更多章节内容可以访问云栖社区 异步社区 公众号查看 1 7 独立且平等 OSPF和IS IS详解与TCP IP相比 OSI协议对各国
  • 【操作系统xv6】学习记录4-一级页表与二级页表

    占位

随机推荐