SHA-1算法详解和C++实现

背景介绍

SHA-1算法也称安全散列算法1,可以将一个最大264−12^{64}-1264−1的数据生成一个160位的数据摘要。尽管SHA-1算法已经被认为不再安全,但仍有部分应用使用SHA-1算法验证文件。

算法原理

类型定义

在介绍算法原理之前,有必要定义一些数据类型,有助于我们脱离具体编程语言分析这个算法。我这里使用C++的定义方式,不会C++也没有问题,我会解释代码的意义。

typedef __UINT8_TYPE__ BYTE;
typedef __UINT32_TYPE__ WORD;
typedef __UINT64_TYPE__ DWORD;

上面定义了三个数据类型,分别是:

  1. BYTE,字节,由8位二进制数组成,表示范围(0x0 - 0xFF)。
  2. WORD,字,由32位二进制数组成,表示范围(0x0 - 0xFFFFFFFF)。
  3. DWORD,双字,两个字组成,表示范围(0x0 - 0xFFFFFFFFFFFFFFFF)

算法剖析

(以下算法分析均建立在大端存储的基础之上,关于大端存储与小端存储对算法的影响,请见C++实现部分关于大端存储与小端存储的具体实现。)

**输入:**不定长度的字节序列(最大为264−12^{64}-1264−1位)。

**输出:**160位数据摘要。

输入不必多说,这里说一下输出。SHA-1算法最终产生160位数据摘要,这实际上由5个变量存储,每个变量存储32位信息,也就是说,这160为数据摘要存储在5个WORD中(5×32=1605\times 32=1605×32=160),这五个变量被定义为:A,B,C,D,E。他们都有初始值,分别为:

WORD A = 0x67452301;
WORD B = 0xEFCDAB89;
WORD C = 0x98BADCFE;
WORD D = 0x10325476;
WORD E = 0xC3D2E1F0;

SHA-1算法的过程就是利用输入的字节序列,不断更新这五个变量,最后将这五个变量按字节拼接,就得到160位的数据摘要。具体过程如下:

1. 数据预处理

SHA-1算法的基本运算单位是一个块(block),一个块的大小为512位,即64字节。输入的数据位数按512被不断分块。如果数据不能被512整除,也就是说最后一部分数据不能填满一块怎么办呢?实际上即便最后一部分填满512位,我们依旧要进行更进一步处理,除非最后一部分刚好等于448位,也就是56个字节。因为我们需要最后一块的最后64个字节填入整个数据的位数长度。所以我们输入的数据有以下两种情况:

  1. 数据位数长度对512取余刚好等于448。
  2. 数据位数长度对512取余不等于448。

对情况1:我们只需要在最后64位中填入输入数据的位数长度即可。

对情况2:这里相对情况1更为复杂,需要进行补位

什么是补位呢?我们需要在数据最后补上一个1,然后全部补0直到数据长度对512取余等于448。例如我们数据为:10011010,长度为8位,补位后为:10011010 1000...0,中间空格为了区分补位数据。补位完成后,最后填入的数据长度依旧是8,补位数据不计入数据长度。

2. 生成子组

由于SHA-1算法的基本运算单位是一个块,所以我们只需对上面分完的这么多个块中讨论一个即可。

对于给定的一个块,512位,我们需要再分成16个子组,每个子组32位。也就是一个WORD,记为w0,w1,...,w15w_0, w_1, ..., w_{15}w0​,w1​,...,w15​,我们需要这16个子组,再生成64个子组,记为w16,w17,...,w79w_{16},w_{17},...,w_{79}w16​,w17​,...,w79​。生成算法如下:
wi=wi−3⊕wi−8⊕wi−14⊕wi−16w_{i} = w_{i-3}\oplus w_{i-8}\oplus w_{i-14}\oplus w_{i-16} wi​=wi−3​⊕wi−8​⊕wi−14​⊕wi−16​
其中i∈{16,...,79}i \in \{16, ..., 79\}i∈{16,...,79},⊕\oplus⊕表示异或,在C++中对应运算符为^

3. 80次核心循环

在循环开始之前,我们需要得到一组A,B,C,D,E五个变量的拷贝,记为a,b,c,d,e。

WORD a = A, b = B, c = C, d = D, e = E;

接下来我们需要执行一个80次的循环,每次循环都利用到a,b,c,d,e,以及一个子组。

第1个20次循环(0 < i < 19):

WORD temp = (b & c) | ((~b) & d) + 0x5A827999;
WORD temp2 = a << 5 | a >> 27;
e = d;
d = c;
c = b << 30 | b >> 2;
b = a;
a = temp + temp2 + e + w[i];

第2个20次循环(20 < i < 39):

WORD temp = (b ^ c ^ d) + 0x6ED9EBA1;
WORD temp2 = a << 5 | a >> 27;
e = d;
d = c;
c = b << 30 | b >> 2;
b = a;
a = temp + temp2 + e + w[i];

第3个20次循环(40 < i < 59):

WORD temp = (b & c) | (b & d) | (c & d) + 0x8F1BBCDC;
WORD temp2 = a << 5 | a >> 27;
e = d;
d = c;
c = b << 30 | b >> 2;
b = a;
a = temp + temp2 + e + w[i];

第4个20次循环(60 < i < 79):

WORD temp = (b ^ c ^ d) + 0xCA62C1D6;
WORD temp2 = a << 5 | a >> 27;
e = d;
d = c;
c = b << 30 | b >> 2;
b = a;
a = temp + temp2 + e + w[i];

执行完之后,这一块的运算已经完成,只需要更新A,B,C,D,E的值即可。

A += a;
B += b;
C += c;
D += d;
E += e;

之后即可进行下一块运算。

C++实现

大小端问题

值得注意的是,SHA-1算法建立在大端存储的基础上,包括填入数据长度时,最后64个字节也是按照大端存储来分配的。但是如果机器时小端存储,这边就会出问题,问题出现的地方在:循环位移运算、加法运算。所以如果是小端存储的机器,必须保证在实际内存上数据的排列按SHA-1算法要求,那么我们必须在取出数据和存入数据时反转数据。

大文件分批次读取计算的问题

关于大文件无法一次性读入内存时,SHA-1算法支持分批次读入,这是由于SHA-1算法计算基础单位是一个块决定的,所以读入大文件时,需要一个变量记住不断累计的文件长度,并且读入数据满一个块时立即计算并清空块缓冲区,等待下一组数据读入。

具体实现

关于C++的具体实现部分我已经在Github上开源,项目名称为justsha1,欢迎各位点个star。

SHA-1算法详解和C++实现相关推荐

  1. Matlab人脸检测算法详解

    这是一个Matlab人脸检测算法详解 前言 人脸检测结果 算法详解 源代码解析 所调用函数解析 bwlabel(BW,n) regionprops rectangle 总结 前言 目前主流的人脸检测与 ...

  2. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

  3. C++中的STL算法详解

    1.STL算法详解 STL提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等.算法就是函数模板,算法通过迭代器来操纵容器中的元素.许多算法操作的是容器上的一个区间(也可以是整个容 ...

  4. 粒子群(pso)算法详解matlab代码,粒子群(pso)算法详解matlab代码

    粒子群(pso)算法详解matlab代码 (1)---- 一.粒子群算法的历史 粒子群算法源于复杂适应系统(Complex Adaptive System,CAS).CAS理论于1994年正式提出,C ...

  5. 基础排序算法详解与优化

    文章图片存储在GitHub,网速不佳的朋友,请看<基础排序算法详解与优化> 或者 来我的技术小站 godbmw.com 1. 谈谈基础排序 常见的基础排序有选择排序.冒泡排序和插入排序.众 ...

  6. 目标检测 RCNN算法详解

    原文:http://blog.csdn.net/shenxiaolu1984/article/details/51066975 [目标检测]RCNN算法详解 Girshick, Ross, et al ...

  7. Twitter-Snowflake,64位自增ID算法详解

    Twitter-Snowflake,64位自增ID算法详解 from: http://www.lanindex.com/twitter-snowflake%EF%BC%8C64%E4%BD%8D%E8 ...

  8. 数据结构与算法详解目录

    数据结构与算法详解是一本以实例和实践为主的图书,主要是经典的数据结构与常见算法案例,来自历年考研.软考等考题,有算法思路和完整的代码,最后提供了C语言调试技术的方法. 后续配套微课视频. 第0章  基 ...

  9. [搜索]波特词干(Porter Streamming)提取算法详解(2)

     接[搜索]波特词干(Porter Streamming)提取算法详解(1), http://blog.csdn.net/zhanghaiyang9999/article/details/4162 ...

  10. 【目标检测】Faster RCNN算法详解

    转载自:http://blog.csdn.net/shenxiaolu1984/article/details/51152614 Ren, Shaoqing, et al. "Faster ...

最新文章

  1. 大数据【四】MapReduce(单词计数;二次排序;计数器;join;分布式缓存)
  2. MySQL优化之查询缓存(mysql8官方已经废弃这个功能)
  3. 大象起舞——微软研发如何保持创新力和敏捷性
  4. java 二进制as_Java中的二进制文本
  5. Cheatsheet: 2010 12.13 ~ 12.23
  6. 迷你星域冒险服务器维护中,迷你世界星域冒险
  7. Java基础学习总结(73)——Java最新面试题汇总
  8. 《Java高并发程序设计》读书笔记 第二章 并行程序基础
  9. 第一次做socket的一些心得
  10. 中国地图经纬度范围,用多个矩形表示大致范围
  11. 咋做数据分析,张口就来RFM模型,结果用错了
  12. 火线精英正在维护服务器吗,火线精英1月20日23:00更新维护公告
  13. 2021高考成绩查询大连,2021大连市地区高考成绩排名查询,大连市高考各高中成绩喜报榜单...
  14. windos下 elasticksearch7.13安装踩坑记
  15. 纯前端文档预览,还要支持所有主流格式,有这一篇就足够了
  16. kindeditor=4.1.5文件上传漏洞复现
  17. 徽章插件_为您的未来项目免费徽章PSD和矢量集
  18. macbook pro下安装三系统
  19. 苹果邮箱怎么登录qq邮箱_gmail邮箱登录官网方法
  20. 前端遇到的那些技术难点

热门文章

  1. 金融工程-复制定价法
  2. Mac 安装brew的正确姿势
  3. Configuration servicename.MapServer can not be started.
  4. 软件测试登录测试用例点
  5. 安装一个Excel插件,轻松网罗50+主流数据库
  6. 解决无法将卷压缩到超出任何不可移动的文件所在的点【磁盘碎片整理】
  7. 手机web页面调用打开QQ聊天功能(个人项目经验)
  8. 火拼折叠屏:国产手机的杀手锏还是遮羞布?
  9. 数据类型(五大基本类型,3种特殊类型)
  10. 清理VS工程的ipch和sdf文件