HASH函数编程

上传人:仙*** 文档编号:60693558 上传时间:2022-03-09 格式:DOC 页数:9 大小:218.11KB
收藏 版权申诉 举报 下载
HASH函数编程_第1页
第1页 / 共9页
HASH函数编程_第2页
第2页 / 共9页
HASH函数编程_第3页
第3页 / 共9页
资源描述:

《HASH函数编程》由会员分享,可在线阅读,更多相关《HASH函数编程(9页珍藏版)》请在装配图网上搜索。

1、上机三:HASH函数编程【上机目的】熟悉HASH函数的基本原理和性质,通过编程/开源代码分析了解一种标准HASH算法的运行原理。【上机环境】1、 硬件 PC机一台。 2、 系统配置:操作系统windows XP以上。 3、编程语言:C/C+/C#/Java/Python【上机内容及要求】1、 MD5算法分析和实现2、 使用实例分析备注:可借鉴网上相关算法的开源代码进行编程实现,编程语言不限;除了MD5算法,也可以选取SHA系列HASH算法(或其它任一种标准的HASH算法)进行研究。【上机报告】实验过程:Python遇到Hash,内置的函数库就可以解决,但要是想理解算法与原理。还是要走一边流程。

2、Python hash库的应用import hashlibpsw=amd5 = hashlib.md5() #初始化摘要对象md5.update(psw.encode(utf-8) #使用md5算法计算print(md5.hexdigest()#输出16进制字符串a的Hash值对应0cc175b9c0f1b6a831c399e269772661让a=bujunjie我的名字hash看来老师让我们分析分析源码吗?要分析源码首先搞一下。什么是HASH?摘要算法是将信息压缩提取以作为数据指纹的算法,我们下载东西要确认下的东西有没有下错下漏常用这种算法来做验证,在密码学中这是很多算法的基础具体摘要算法

3、是怎么样的?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)还有一种应用场景是用来存储用户的密码,大明文密码存储在数据库里很不安全,之前爆出很多知名网站将用户密码以明文存储,导致信息泄露.可以通过摘要算法给密码加个密存储进去.这样要破解密码除了要知道密码本身,还得知道生成最终摘要文本的算法才可以.也就相对安全多了。MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。dis

4、playstyle oplus ,wedge ,vee ,neg -摘自wiki百科/Note: All variables are unsigned 32 bits and wrap modulo 232 when calculatingvar int64 r, k/r specifies the per-round shift amountsr 0.15:= 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 r16.31:= 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 1

5、4, 20r32.47:= 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23r48.63:= 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21/Use binary integer part of the sines of integers as constants:for i from 0 to 63 ki := floor(abs(sin(i + 1) 232)/Initialize variables:var int h0 := 0x67452301va

6、r int h1 := 0xEFCDAB89var int h2 := 0x98BADCFEvar int h3 := 0x10325476/Pre-processing:append 1 bit to messageappend 0 bits until message length in bits 448 (mod 512)append bit length of message as 64-bit little-endian integer to message/Process the message in successive 512-bit chunks:for each 512-b

7、it chunk of message break chunk into sixteen 32-bit little-endian words wi, 0 i 15 /Initialize hash value for this chunk: var int a := h0 var int b := h1 var int c := h2 var int d := h3 /Main loop: for i from 0 to 63 if 0 i 15 then f := (b and c) or (not b) and d) g := i else if 16 i 31 f := (d and

8、b) or (not d) and c) g := (5i + 1) mod 16 else if 32 i 47 f := b xor c xor d g := (3i + 5) mod 16 else if 48 i 63 f := c xor (b or (not d) g := (7i) mod 16 temp := d d := c c := b b := leftrotate(a + f + ki + wg),ri) + b a := temp Next i /Add this chunks hash to result so far: h0 := h0 + a h1 := h1

9、+ b h2 := h2 + c h3 := h3 + dEnd ForEachvar int digest := h0 append h1 append h2 append h3 /(expressed as little-endian)wiki的伪代码。大概的意思就是经过64次运算,在经过4轮,然后将32位的加起来。# codeing=utf-8# 引入math模块,因为要用到sin函数import math# 定义常量,用于初始化128位变量,注意字节顺序,文中的A=0x01234567,这里低值存放低字节,即01 23 45 67,所以运算时A=0x67452301,其他类似。# 这里

10、用字符串的形势,是为了和hex函数的输出统一,hex(10)输出为0xA,注意结果为字符串。A = 0x67452301B = 0xefcdab89C = 0x98badcfeD = 0x10325476# 定义每轮中用到的函数。L为循环左移,注意左移之后可能会超过32位,所以要和0xffffffff做与运算,确保结果为32位。F = lambda x, y, z: (x & y) | (x) & z)G = lambda x, y, z: (x & z) | (y & (z)H = lambda x, y, z: (x y z)I = lambda x, y, z: (y (x | (z)L

11、 = lambda x, n: (x (32 - n) & (0xffffffff)# 定义每轮中循环左移的位数,这里用4个元组表示,用元组是因为速度比列表快。shi_1 = (7, 12, 17, 22) * 4shi_2 = (5, 9, 14, 20) * 4shi_3 = (4, 11, 16, 23) * 4shi_4 = (6, 10, 15, 21) * 4# 定义每轮中用到的Mi次序。m_1 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)m_2 = (1, 6, 11, 0, 5, 10, 15, 4, 9, 1

12、4, 3, 8, 13, 2, 7, 12)m_3 = (5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2)m_4 = (0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9)# 定义函数,用来产生常数Ti,常数有可能超过32位,同样需要&0xffffffff操作。注意返回的是十进制的数。def T(i): result = (int(4294967296 * abs(math.sin(i) & 0xffffffff return result# 定义函数,用来将列表中的元素循环右移。原

13、因是在每轮操作中,先运算A的值,然后是D,C,B,16轮之后右恢复原来顺序,所以只要每次操作第一个元素即可。def shift(shift_list): shift_list = shift_list3, shift_list0, shift_list1, shift_list2 return shift_list# 定义主要的函数,参数为当做种子的列表,每轮用到的F,G,H,I,生成的M,以及循环左移的位数。该函数完成一轮运算。def fun(fun_list, f, m, shi): count = 0 global Ti_count # 引入全局变量,T(i)是从1到64循环的。 whi

14、le count 0x67452301def reverse_hex(hex_str): hex_str = hex_str2: hex_str_list = for i in range(0, len(hex_str), 2): hex_str_list.append(hex_stri:i + 2) hex_str_list.reverse() hex_str_result = 0x + .join(hex_str_list) return hex_str_result# 显示结果函数,将最后运算的结果列表进行翻转,合并成字符串的操作。def show_result(f_list): res

15、ult = f_list1 = 0 * 4 for i in f_list: f_list1f_list.index(i) = reverse_hex(i)2: result = result + f_list1f_list.index(i) return result# 程序主循环while True: abcd_list = A, B, C, D Ti_count = 1 input_m = raw_input(msg) # 对每一个输入先添加一个0x80,即10000000 ascii_list = map(hex, map(ord, input_m) msg_lenth = len(a

16、scii_list) * 8 ascii_list.append(0x80) # 补充0 while (len(ascii_list) * 8 + 64) % 512 != 0: ascii_list.append(0x00) # 最后64为存放消息长度,注意长度存放顺序低位在前。 # 例如,消息为a,则长度为0x0800000000000000 msg_lenth_0x = hex(msg_lenth)2: msg_lenth_0x = 0x + msg_lenth_0x.rjust(16, 0) msg_lenth_0x_big_order = reverse_hex(msg_lenth_

17、0x)2: msg_lenth_0x_list = for i in range(0, len(msg_lenth_0x_big_order), 2): msg_lenth_0x_list.append(0x + msg_lenth_0x_big_orderi:i + 2) ascii_list.extend(msg_lenth_0x_list) print ascii_list # 对每个分组进行4轮运算 for i in range(0, len(ascii_list) / 64): # 将最初128位种子存放在变量中, aa, bb, cc, dd = abcd_list # 根据顺序产

18、生每轮M列表 order_1 = genM16(m_1, ascii_list, i) order_2 = genM16(m_2, ascii_list, i) order_3 = genM16(m_3, ascii_list, i) order_4 = genM16(m_4, ascii_list, i) # 主要四轮运算,注意打印结果列表已经被进行过右移操作! abcd_list = fun(abcd_list, F, order_1, shi_1) print - abcd_list = fun(abcd_list, G, order_2, shi_2) print - abcd_lis

19、t = fun(abcd_list, H, order_3, shi_3) print - abcd_list = fun(abcd_list, I, order_4, shi_4) print - # 将最后输出与最初128位种子相加,注意,最初种子不能直接使用abcd_list0等,因为abcd_list已经被改变 output_a = hex(int(abcd_list0, 16) + int(aa, 16) & 0xffffffff):-1 output_b = hex(int(abcd_list1, 16) + int(bb, 16) & 0xffffffff):-1 output_

20、c = hex(int(abcd_list2, 16) + int(cc, 16) & 0xffffffff):-1 output_d = hex(int(abcd_list3, 16) + int(dd, 16) & 0xffffffff):-1 # 将输出放到列表中,作为下一次128位种子 abcd_list = output_a, output_b, output_c, output_d # 将全局变量Ti_count恢复,一遍开始下一个分组的操作。 Ti_count = 1 # 最后调用函数,格式化输出 print md5 + show_result(abcd_list)运行调试输入上面用hash库跑出来的a,然后做对比。中间输出四轮中的每一轮的加密过程与结果。A的md5:md50cc175b9c0f1b6a831c399e269772661验证成功。对我的名字进行hashHash= bujunjiemd5167bf89be4c09c5bf26adcaac663e2d3实验结果相同。试验成功。实验心得:通过实验让我对hash的加密的原理有了更深的了解。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!