前言
雪崩效应
计算字符串的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
结束语:
文章可能存在错误,欢迎指出。