英文:
What is wrong with this md5 implementation
问题
以下是有关此MD5实现的问题的翻译:
- 我尝试了一切可能的方法来使其工作,但结果与文章中给出的伪代码不符。这是因为不同的编码系统吗?
- 任何帮助将不胜感激。
链接:https://en.wikipedia.org/wiki/MD5#Algorithm
#这段代码与https://en.wikipedia.org/wiki/MD5#Algorithm中的伪代码一一对应
#-------------全局变量开始 ----------------------#
from math import sin , floor
import math
S = [
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
]
K = [floor(abs(math.sin(i + 1)) * (2 ** 32)) & 0xFFFFFFFF for i in range(64)]
rotate = lambda x,n:((x << n) | (x >> (32 - n))) & 0xFFFFFFFF
#-------------全局变量结束------------------------#
def md5(text):
a0 = 0x67452301
b0 = 0xefcdab89
c0 = 0x98badcfe
d0 = 0x10325476
length = len(text)
text = text + b'\x80'
text += (b'\x00' * (512 - (len(text) * 8 % 512)))
text = text + length.to_bytes(8, 'little')
for i in range(0, len(text), 64):
chunk = text[i:i+64]
M = [int.from_bytes(chunk[j:j+4], 'little') for j in range(0, 64, 4)]
A = a0
B = b0
C = c0
D = d0
for j in range(64):
if 0 <= j <= 15:
F = (B & C) | ((~B) & D)
g = j
elif 16 <= j <= 31:
F = (D & B) | ((~D) & C)
g = ((5 * j) + 1) % 16
elif 32 <= j <= 47:
F = B ^ C ^ D
g = ((3 * j) + 5) % 16
elif 48 <= j <= 63:
F = C ^ (B | (~D))
g = (7 * j) % 16
F = (F + A + K[j] + M[g]) & 0xFFFFFFFF
A, D, C, B = D, C, B, (B + rotate(F, S[j])) & 0xFFFFFFFF
a0 = (a0 + A) & 0xFFFFFFFF
b0 = (b0 + B) & 0xFFFFFFFF
c0 = (c0 + C) & 0xFFFFFFFF
d0 = (d0 + D) & 0xFFFFFFFF
result = (a0.to_bytes(4, 'little') +
b0.to_bytes(4, 'little') +
c0.to_bytes(4, 'little') +
d0.to_bytes(4, 'little'))
return result.hex()
text = 'The quick brown fox jumps over the lazy dog'.encode("utf-8")
print(md5(text))
输出:
171e495fea830541b8542c338e388a97
预期输出:
9e107d9d372bb6826bd81d3542a419d6
英文:
What is wrong with this md5 implementation
I tried all the possible thing to get it working but wrong result compared to the pseudocode given in article.
Does this is because of different encoding System.
Any Help Would be appreciated.
https://en.wikipedia.org/wiki/MD5#Algorithm
#This Code has one to one correspondance with https://en.wikipedia.org/wiki/MD5#Algorithm psuedocode
#-------------Globals Start ----------------------#
from math import sin , floor
import math
S = [
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
]
K = [floor(abs(math.sin(i + 1)) * (2 ** 32)) & 0xFFFFFFFF for i in range(64)]
rotate = lambda x,n:((x << n) | (x >> (32 - n))) & 0xFFFFFFFF
#-------------Globals End------------------------#
def md5(text):
a0 = 0x67452301
b0 = 0xefcdab89
c0 = 0x98badcfe
d0 = 0x10325476
length = len(text)
text = text + b'\x80'
text += (b'\x00' * (512 - (len(text) * 8 % 512)))
text = text + length.to_bytes(8, 'little')
for i in range(0, len(text), 64):
chunk = text[i:i+64]
M = [int.from_bytes(chunk[j:j+4], 'little') for j in range(0, 64, 4)]
A = a0
B = b0
C = c0
D = d0
for j in range(64):
if 0 <= j <= 15:
F = (B & C) | ((~B) & D)
g = j
elif 16 <= j <= 31:
F = (D & B) | ((~D) & C)
g = ((5 * j) + 1) % 16
elif 32 <= j <= 47:
F = B ^ C ^ D
g = ((3 * j) + 5) % 16
elif 48 <= j <= 63:
F = C ^ (B | (~D))
g = (7 * j) % 16
F = (F + A + K[j] + M[g]) & 0xFFFFFFFF
A, D, C, B = D, C, B, (B + rotate(F, S[j])) & 0xFFFFFFFF
a0 = (a0 + A) & 0xFFFFFFFF
b0 = (b0 + B) & 0xFFFFFFFF
c0 = (c0 + C) & 0xFFFFFFFF
d0 = (d0 + D) & 0xFFFFFFFF
result = (a0.to_bytes(4, 'little') +
b0.to_bytes(4, 'little') +
c0.to_bytes(4, 'little') +
d0.to_bytes(4, 'little'))
return result.hex()
text = 'The quick brown fox jumps over the lazy dog'.encode("utf-8")
print(md5(text))
Output:
171e495fea830541b8542c338e388a97
Expected Output
9e107d9d372bb6826bd81d3542a419d6
答案1
得分: 1
你的填充方式不正确,以下这些行:
text += b'\x00' * (512 - (len(text) * 8 % 512))
text = text + length.to_bytes(8, 'little')
应该改成:
text += b'\x00' * (56 - (len(text) % 64))
text = text + (length * 8).to_bytes(8, 'little')
解释:
看起来你混淆了位和字节的值。你的消息是以字节为单位的,这意味着 len(text)
表示的是字节长度。因此,在计算需要填充的量时,我们需要使用字节值。
同样,在下一行中,由于 length
是字节值,所以在附加它之前,我们需要将它转换为位值(根据规范)。
英文:
You are padding incorrectly, the lines:
text += (b'\x00' * (512 - (len(text) * 8 % 512)))
text = text + length.to_bytes(8, 'little')
should instead be:
text += b'\x00' * (56 - (len(text) % 64))
text = text + (length * 8).to_bytes(8, 'little')
Explanation:
It seems you are getting confused between bit and byte values. Your message is in bytes which means
len(text)
is the message length in bytes. Consequently, when calculating the amount to pad we need to use byte values.
Similarly on the next line since length
is a byte value we need to convert it to a bit value before appending it (according to the spec).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论