SHA-256算法详解——Github工程结合示例和动画演示

近日笔者在学习区块链的相关知识,接触到SHA-256算法,这里做一个知识梳理和总结。

强烈推荐大家自行去学习下面链接github上的工程,作者的动画演示和解释做的非常出色,逻辑非常清晰,B站搬运的对应的油管的讲解视频也放在下面,本文也是基于此github工程和作者学习过程的思路进行呈现。

github:

https://github.com/in3rsha/sha256-animation

B站讲解视频:

https://www.bilibili.com/video/BV1Jg411G7tc

ruby(windows)安装教程:

https://www.cnblogs.com/minisayo/p/14015747.html

可以先将github工程下载到本地,因为作者是用的ruby进行动画展示,所以需要再windows/Linux系统上安装ruby,之后在工程目录下调用ruby xxx.rb指令即可啦。

下面是整个工程的流程图,也对应着SHA-256算法的设计思路。

一、运算定义

为了后续分析思路与流程的连贯性,在这里先统一声明一下一些运算的定义,后续一些函数会直接对这些运算进行封装使用。

1、右移Right Shift (shr.rb)

这里的右移会产生两种结果,第一种结果是左侧移动完之后位为0,右侧被移走的位丢失,如上图所示SHR 32的操作,原数据为32位,在右移32位之后原数据都被右移丢失,剩下的左侧移动完的位全为0。

2、旋转右移Right Shift (rotr.rb)

这里要尤其注意和SHR右移的区别,观察演示图可以发现对于旋转右移而言数据组成了一个环形,移动位数只是改变位的绝对位置,并不会丢弃数据,所以原数据32位,再进行ROTR 32的操作实际上就是所有数据位旋转了一整圈,又回到了原来的位置。

3、异或XOR (xor.rb)

按位异或,0^0 = 0,1^0 = 1,0^1 = 1,1^1 = 0。

4、加法Addition (add.rb) 

这里和二进制加法一样,但是由于多个32位的数据相加,最终的存在着溢出的风险,因此最终的结果进行取模2*32将其约束在32位输出。

二、函数定义

第一部分的运算被封装组合起来就是这部分的函数,在这里先列出一些后续算法流程分析会用到的函数,读者可以先有个大概印象,后面第三部分算法流程分析的时候再回看也可以。

前四个函数使用希腊符号 Sigma(小写 σ,大写 Σ)命名。这些名称没有特殊含义,只是为了方便给一些组合运算命名。

1、σ0 (sigma0.rb)

σ0(x) = ROTR7(x) ^ ROTR18(x) ^ SHR3(x)

先分别计算ROTR 7位和ROTR18位和SHR 3位,再将三者异或

2、σ1 (sigma1.rb)

σ1(x) = ROTR17(x) ^ ROTR19(x) ^ SHR10(x)

先分别计算ROTR 17位和ROTR 19位和SHR 10位,再将三者异或

3、Σ0 (usigma0.rb)

Σ0(x) = ROTR2(x) ^ ROTR13(x) ^ ROTR22(x)

先分别计算ROTR 2位和ROTR 13位和ROTR 22位,再将三者异或

4、Σ1 (usigma1.rb) 

Σ1(x) = ROTR6(x) ^ ROTR11(x) ^ ROTR25(x)

先分别计算ROTR 6位和ROTR 11位和ROTR 25位,再将三者异或

5、Choice (ch.rb)

这个函数使用x位在y位和z位之间进行选择。如果x=1,则选择y位;如果x=0,则选择z位。

6、Majority (maj.rb)  

这个函数返回三位中的多数位。

7、常量Constants (constants.rb)

SHA-256 使用六十四个常量 Kt 来帮助在主哈希计算过程中混合比特。

首先计算前64个质数的立方根,然后取其小数部分乘2^32,将得到的常量作为Kt使用,其中t表示第t个质数运算后的结果。

这些立方根的小数部分是无理数(它们无限延伸),因此它们是用于常量的良好随机比特选择。这比使用特别选择的常量更好,因为这降低了哈希函数被设计成具有后门的可能。

三、算法流程分析 

在这里message的内容是可以自己指定的,我们以message = dyq 为例(在每个rb文件的开头可以自定义默认输入)

1、message.rb 

输入一个message字符串时,我们将每个字符转换为 ASCII 表中的对应数字。这些数字被转换为二进制,我们使用这些二进制数据作为哈希函数的输入。 

2、padding.rb

SHA-256 哈希函数以 512 位的block数据块为单位进行操作,因此所有消息都需要用零填充至最接近的 512 位的倍数,可以是512、1024等,这里先填充到448位,后64位预留出用来表示message的比特位数。

为了防止相似输入哈希到相同的结果,我们用 1 位将消息与零分隔开,并在填充的最后 64 位中包含消息的大小。 

以上这种用 1 分隔消息并在填充中包含消息大小的方法被称为 Merkle–Damgård 加强(MD 加强)。 

3、blocks.rb

消息经过填充后,我们将其切割成等长的 512 位消息块 Mi 以便哈希函数处理。

每个消息块也可以进一步分成 16 个词Wj ( 512 / 32 = 16 words ),每个词的长度为32bit,这将在后续使用。 

4、schedule.rb

 对于前16个word,每个word有32个bit,相当于是把原本的block0分为了32*16。

从第17个word开始根据下面的公式进行计算

Wt = σ1(Wt-2) + Wt-7 + σ0(Wt-15) + Wt-16

其中σ1和σ0在第二部分可以找到函数的定义。

5、expansion.rb

这一步展示的是上面最后一个word W63生成的运算过程。 

6、initial.rb

初始哈希值使用了前八个质数的平方根的小数部分。我们将这八个字母作为状态寄存器,我们可以将其作为开始哈希计算的起点(初始状态)

7、t1.rb t2.rb

我们需要先使用状态寄存器中的当前值来计算两个新的临时词( T1 和 T2 ),为后续的压缩过程做准备。

T1 = Σ1(e) + Ch(e, f, g) + h + Kt + Wt

其中Σ1和Ch函数在第二部分,h为h状态寄存器存储的值,Kt为第二部分的64个常数值,Wt为schedule.rb求得的word。

T2 = Σ0(a) + Maj(a, b, c)

其中Σ0函数和Maj函数均在第二部分。

8、compression.rb

压缩是整个算法的核心。我们再将其细化进行分析

(1) step1:计算出T1和T2

 (2) step2:所有寄存器下移一个

 (3) step3:更新a和e寄存器的值

以上三步可以概括为计算T1,T2;下移寄存器;更新a和e值,至此我们称为完成一轮压缩。这样的压缩要对一共64个word都进行一遍。

以上就是第二轮的step1开始以此类推。 

压缩完64轮之后,将最终的abcdefgh寄存器的值和initial.rb中的abcdefgh中的值相加得到最后的寄存器值

如果还有进一步要处理的消息块(block1,block2……),按照下图当前的哈希值将作为下一个压缩的初始哈希值。 

9、final.rb

 最终将8个32位的寄存器值转化为8个16进制的哈希值并拼接在一起,最终得到message的哈希值

 

使用哈希计算器验证一下是没问题的

10、sha256.rb 

# 直接进行哈希运算
ruby sha256.rb abc# 也可以输出二进制和十六进制数据
ruby sha256.rb 0b01100001
ruby sha256.rb 0xaabbccdd# 哈希一个文件 (请注意,文件末尾将有一个换行符)
ruby sha256.rb file.txt# 添加不同的命令行参数
ruby sha256.rb abc normal # 默认
ruby sha256.rb abc fast   # 加速演示
ruby sha256.rb abc enter  # 每按一次回车,步进一次动画

sha256.rb是一个集成上述功能的完整代码,除此之外,还可以指定命令行参数实现不同操作。

将sha-256.rd的输出改成可分为多个block的长message,测试多个block条件下hash算法 

观察以上代码运行后的结果发现,进行了多个block的流水线运算,最终的结果正确,真是太吊了。但是这里注意改变输入时不能直接在命令行输入段落,因为作者的代码中不能识别空格,所以只能在rb文件里改变input,但是也无伤大雅,笔者有时间会完善一下这个小bug的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88293.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言模块化编程思维以及直流电机控制(第四天)

👨‍💻个人主页:开发者-削好皮的Pineapple! 👨‍💻 hello 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 削好皮的Pineapple! 原创 👨‍&#x1f4…

【PTA】数据结构与算法0001:1025 反转链表

文章大纲写在前面测试用例ac代码学习代码知识点小结写在前面 实现思路 结构体封装数据 根据order重新排序k区间值迭代翻转 n整除k,则最后地址输出"-1"非整除,最后剩余区间,原序输出。最后地址输出"-1" 题目有难度&…

深入解析 .NET 泛型:从原理到实战优化

在现代软件开发中,代码复用性和性能优化是开发者永恒的追求。.NET 泛型作为一项强大的语言特性,不仅能够帮助我们消除重复代码,还能显著提升代码的类型安全性和运行效率。本文将带你全面了解 .NET 泛型,从基本概念到高级用法&…

Excel 处理软件 内容复制工具:工作表批量复制 + 合并拆分简洁操作零门槛

各位办公小能手们!今天给你们介绍一款超牛的软件——Excel内容复制工具。软件下载地址安装包 这可是专门为了让Excel数据处理效率蹭蹭往上涨而设计的辅助软件呢!它的主要功能可多啦,能批量复制工作表,还能把好多表格合并到同一个…

【机器学习实战笔记 14】集成学习:XGBoost算法(一) 原理简介与快速应用

《XGBoost算法》 推荐的学习路径: 【快速实现XGBoost、跑通代码】- 第一部分 【快速掌握XGBoost应用、达到自由调参水平】- 第一部分~第三部分 【快速掌握XGBoost原理、面试得以通关】- 第一部分1 第二部分1.2、2.2 第四部分 目录《XGBoost算法》一 XGBoost的基…

.NET AI 模板

引言 随着人工智能技术的快速发展,AI应用开发已成为开发者必备的技能之一。然而,对于许多.NET开发者来说,如何快速上手AI开发仍然是一个挑战。微软推出的.NET AI模板预览版正是为了解决这一问题而生,为开发者提供了构建智能聊天应…

EFK9.0.3 windows搭建

背景 最近某个功能要使用到ELK(ElasticSearch、Logstash、Kibana)采集日志,对数据进行分析,网上百度了一下,目前推荐不使用Logstash而使用Filebeat ,即EFK。 下载链接 Elasticsearch Kibana Filebeat 安装前提 …

上海新华医院奉贤院区:以元宇宙技术重构未来医疗生态

引言:当医疗遇上元宇宙在数字化转型的浪潮中,上海新华医院奉贤院区以"智慧医院"为定位,率先构建了"元宇宙医院"雏形。通过AI大模型、三维影像分析、AR手术导航等前沿技术的深度融合,医院正在打造一个覆盖全周…

知识竞赛答题pk小程序用户操作手册

知识竞赛答题 PK 小程序用户操作手册 一、注册与登录 用户首次使用答题pk小程序需上传头像,输入昵称,并选择加入团队。如果是企业内部人员使用可开启白名单功能。二、进入答题 PK 模式 登录后,在小程序首页,您可以看到 “单人挑战…

等大小谱聚类

聚类是一种将具有相似特征的数据点进行分组的方法。它广泛应用于探索性数据分析,并已被证明在模式识别、市场和客户细分、推荐系统、数据压缩以及生物数据分析等许多应用中都发挥着重要作用。 尽管聚类算法种类繁多,但没有一种能够生成点数均衡的聚类。…

〔从零搭建〕数据湖平台部署指南

🔥🔥 AllData大数据产品是可定义数据中台,以数据平台为底座,以数据中台为桥梁,以机器学习平台为中层框架,以大模型应用为上游产品,提供全链路数字化解决方案。 ✨杭州奥零数据科技官网&#xff…

Java 导出pdf 写出demo 1、需要设置自定义页眉和文字 2、可以插入表格 3、可以插入图片

以下是一个使用 iText 7 库实现 PDF 导出的 Java 示例&#xff0c;包含自定义页眉、文字、表格和图片功能&#xff1a; 添加 Maven 依赖 <dependencies><!-- iText 7 Core --><dependency><groupId>com.itextpdf</groupId><artifactId>ite…

Ntfs!LfsReadRestart函数分析得到Ntfs!LFS_RESTART_PAGE_HEADER

第一部分&#xff1a;0: kd> p Ntfs!LfsPinOrMapData0x8c: f71797f6 ff15a40016f7 call dword ptr [Ntfs!_imp__CcPinRead (f71600a4)] 0: kd> t nt!CcPinRead: 80bf9a5a 6a2c push 2Ch 0: kd> kc# 00 nt!CcPinRead 01 Ntfs!LfsPinOrMapData 02 N…

skywalking-agent-docker镜像

FROM centos:7.9.2009 USER root# 定义 Arthas 目录环境变量 ENV ARTHAS_HOME/opt/arthas# 更改 YUM 源并清理缓存 RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak && \rm -rf /etc/yum.repos.d/* && \curl -o /etc/yum.rep…

数据库开发运维的集成:弥合开发与运维之间的鸿沟

在传统的软件开发工作流程中&#xff0c;数据库变更往往是事后才考虑的问题。应用程序代码遵循定义明确的开发运维实践&#xff0c;包括版本控制、自动测试和持续部署&#xff0c;而数据库变更则经常是由数据库管理员手动执行的高风险操作。这种脱节造成了瓶颈&#xff0c;带来…

PiscTrace应用:从 YOLO-Pose 到深蹲与引体向上计数:实时健身动作分析与实现

随着健身行业的发展&#xff0c;越来越多的智能应用涌现&#xff0c;用于帮助健身者更好地记录和分析运动情况。特别是在体能训练中&#xff0c;俯卧撑和引体向上是两个非常常见的动作&#xff0c;它们通常用来锻炼上半身力量和耐力。为了使训练更加科学和高效&#xff0c;实时…

【unity】webCanvas.enabled = false;和webCanvas.gameObject.SetActive(false);的优缺点比较

在 Unity 中&#xff0c;webCanvas.gameObject.SetActive(false) 和 webCanvas.enabled false 是两种不同的隐藏 UI 的方式&#xff0c;它们的核心区别在于作用范围和对组件状态的影响。理解这些差异能帮助你避免初始化失败、性能问题和逻辑错误。 1核心区别 gameObject.SetAc…

深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案

引言 在现代 JavaScript 开发中&#xff0c;依赖管理效率直接影响开发体验。传统工具如 npm 和 yarn 在大型项目中常面临磁盘冗余和性能瓶颈。pnpm&#xff08;Performant npm&#xff09;通过创新的硬链接和符号链接机制&#xff0c;解决了这些痛点。本文将深入解析 pnpm 的核…

Hive MetaStore的实现和优化

在大数据领域&#xff0c;数据管理与存储至关重要&#xff0c;Hive MetaStore&#xff08;HMS&#xff09;作为 Hive 数据仓库的核心组件&#xff0c;承担着元数据管理的关键职责。随着数据规模不断膨胀&#xff0c;其性能与稳定性面临挑战。本文将深入剖析 HMS 的实现机制&…

一文读懂动态规划:多种经典问题和思路

一、动态规划算法的思想与核心概念框架 1. 动态规划的基本思想 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种通过将复杂问题分解为重叠子问题&#xff0c;并利用子问题的解来高效解决原问题的方法。其核心思想是避免重复计算&#xff0c;通过存储中间结果&a…