哈希函数的雪崩效应

本文介绍了如何使用Python实现计算字符串MD5值时,通过翻转特定字节的某一位,观察Avalanche效应,即一个比特变化导致的哈希值差异。作者提供了替换字节、16进制转2进制和不同比特位比较的函数实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

雪崩效应

计算字符串的MD5值为H1,然后翻转其中某个字节的某一bit位,再计算MD5值为H2 比较H1和H2不同位的数量。某一bit位的变化会至少发生一半bit位的变化。

一、编程要求

根据输入的字符串、第几个字节、第几个bit位,计算输出MD5值不同位的数量。 注意:字节从低位到高位数,例如字符串python,第一个字节是对应字母n;同样的,字节中的位也是从低位到高位数。

二、具体实现

字符串的MD5值可以直接调库函数直接得到,主要是将字符串的某个字节的某个比特翻转。下面直接介绍

三、字符串替换

def replaceStr(str,nbyte,mbit):
    str1=str.encode()
    replace_byte=hex(str1[-nbyte])
    res=""
    for i in range(2,len(replace_byte)):
        decimal_num=int(replace_byte[i],16)
        binary_num=format(decimal_num,"04b")
        res=res+binary_num
    temp_list = list(res)
    if res[-mbit]=="1":
        temp_list[-mbit]='0'
    else:
        temp_list[-mbit] ='1'

    res = "".join(temp_list)
    letter=chr(int(res,2))
    res_list=list(str)
    res_list[-nbyte]=letter
    return "".join(res_list)

我的思路:首先将字符串encode()为字节类型,再将要改变的那个字节转换为16进制表示且单独来出来处理,然后通过int()函数得到它的十进制值,再将这个10进制值格式化转化为二进制的字符串,由于python字符串不可变,且后面还要改变比特位,故将其转化为列表,在将列表中要翻转的比特位翻转,然后将其转化为字符串,在通过chr函数将这个字符串的十进制值转化为unicode编码的字符,再用这个字符去替代原来字符串的字符即可。

四、16进制字符串转2进制字符串

def hex_to_bin(hexStr):
    res=""
    for digit in hexStr:
        decimal_num=int(digit,16)
        binary_num=format(decimal_num,"04b")
        res+=binary_num
    return res

五、不同比特位比较

def cmpcount(str1,str2):
    count=0
    for i in range(len(str1)):
        if str1[i]!=str2[i]:
            count+=1
    return count

六、完整代码

import hashlib
def avalanche(str,nbyte,mbit):
    # param str:计算哈希值的字符串
    # param nbyte:str的第几个字节(从低位到高位数)
    # parem mbit: nbyte的第几个bit位(从低位到高位数)
    str1=replaceStr(str,nbyte,mbit)
    res1=hashlib.md5()
    res1.update(str.encode())
    res1=res1.hexdigest()

    res2 = hashlib.md5()
    res2.update(str1.encode())
    res2 = res2.hexdigest()

    str_bit1=hex_to_bin(res1)

    str_bit2=hex_to_bin(res2)

    count=cmpcount(str_bit1,str_bit2)
    print(count)

def hex_to_bin(hexStr):
    res=""
    for digit in hexStr:
        decimal_num=int(digit,16)
        binary_num=format(decimal_num,"04b")
        res+=binary_num
    return res
def cmpcount(str1,str2):
    count=0
    for i in range(len(str1)):
        if str1[i]!=str2[i]:
            count+=1
    return count
def replaceStr(str,nbyte,mbit):
    str1=str.encode()
    replace_byte=hex(str1[-nbyte])
    res=""
    for i in range(2,len(replace_byte)):
        decimal_num=int(replace_byte[i],16)
        binary_num=format(decimal_num,"04b")
        res=res+binary_num
    temp_list = list(res)
    if res[-mbit]=="1":
        temp_list[-mbit]='0'
    else:
        temp_list[-mbit] ='1'

    res = "".join(temp_list)
    letter=chr(int(res,2))
    res_list=list(str)
    res_list[-nbyte]=letter
    return "".join(res_list)

if __name__ == "__main__":
    str,nbyte,mbit = input().split()
    nbyte = int(nbyte)
    mbit = int(mbit)
    avalanche(str,nbyte,mbit)

七、测试结果

测试输入:python 2 1
输出:70

结束语:

文章可能存在错误,欢迎指出。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值