我的ripemd160 Python代码有什么问题?

1 投票
2 回答
4219 浏览
提问于 2025-04-15 18:22

我尝试的所有方法都给了我错误的输出结果。我甚至复制了C语言的代码,然后修改成可以在Python中运行的版本,但结果还是不对。到底出了什么问题呢?

import os, math

def makehex(value,size=8):
    value = hex(value)[2:]
    if value[-1] == 'L':
        value = value[0:-1]
    while len(value)<size:
        value = '0' + value
    return value

def makebin(value,size=32):
    value = bin(value)[2:]
    while len(value)<size:
        value = '0' + value
    return value

def ROL(value,n):
    return (value << n) | (value >> 32-n)

def little_end(string,base = 16):
    t = ''
    if base == 2:
        s= 8
    if base == 16:
        s = 2
    for x in range(len(string)/s):
        t = string[s*x:s*(x+1)] + t
    return t

def F(x,y,z,round):
    if round<16:
        return x ^ y ^ z
    elif 16<=round<32:
        return (x & y) | (~x & z)
    elif 32<=round<48:
        return (x | ~y) ^ z
    elif 48<=round<64:
        return (x & z) | (y & ~z)
    elif 64<=round:
        return x ^ (y | ~z)

def RIPEMD160(data):

# constants
    h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE;h3 = 0x10325476; h4 = 0xC3D2E1F0

    k  = [0, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]
    kk = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9,0]
    s =     [   11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,
            7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,
            11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,
            11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,
            9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]
    ss=     [   8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,
            9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,
            9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,
            15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,
            8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]
    r= range(16) + [    7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
                3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
                1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
                4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]
    rr =    [   5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
            6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
            15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
            8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
            12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]   

    # md4 padding + preprocessing
    temp = ''
    for x in data:
        temp += makebin(ord(x),8)
    length = len(temp)%2**64
    temp +='1'
    while len(temp)%512!=448:
        temp+='0'
    input = temp
    temp = ''
    for x in range(len(input)/32):
        temp += little_end(input[32*x:32*(x+1)],2)
    input = temp
    temp = makebin(length,64)
    input += temp[32:]+temp[:32]
    t = len(input)/512


    # the rounds
    for i in range(t):

            # i called the parallel round variables 2x the other round variable: a -> aa
        a = aa = h0; b = bb = h1; c = cc = h2; d = dd = h3; e = ee = h4
        X = input[512*i:512*(i+1)]
        X = [int(X[32*x:32*(x+1)],2) for x in range(16)]

        for j in range(80):
            T = (a+ ROL( (F(b, c, d, j) + X[r[j]] + k[j/16])%2**32,s[j])+e)%2**32
            c = ROL(c, 10)
            a = e; e = d; d = c; c = b; a = T
            T = (aa+ ROL( (F(bb,cc,dd,79-j) + X[rr[j]] + kk[j/16] )%2**32,ss[j])+ee)%2**32
            cc = ROL(cc,10)
            aa = ee; ee = dd; dd = cc; cc = bb; aa = T

        T  = (h1+c+dd)%2**32
        h1 = (h2+d+ee)%2**32
        h2 = (h3+e+aa)%2**32
        h3 = (h4+a+bb)%2**32
        h4 = (h0+b+cc)%2**32
        h0 = T

    return little_end(makehex(h0))+little_end(makehex(h1))+little_end(makehex(h2))+little_end(makehex(h3))+little_end(makehex(h4))

    data = RIPEMD160('')
    print data,data =='9c1185a5c5e9fc54612808977ee8f548b2258d31'   # its always false

2 个回答

2

不管那些反对的人怎么说,你的代码都是很漂亮的。我在尝试让我的代码正常工作时发现了这一点。我不得不和你的代码一起调试一个C语言库。

这里有几个错误。

  1. 这个是获取字符的ASCII值的二进制,而不是实际的值。

    temp += makebin(ord(x),8)
    
  2. 在对X进行小端处理之前,先添加小端长度。

  3. 在进行ROL操作之前加一个。
  4. 对c和T进行掩码处理。你的ROL函数返回的是44位的数字。

    import os, math
    
    def makehex(value,size=8):
        value = hex(value)[2:]
        if value[-1] == 'L':
            value = value[0:-1]
        while len(value)<size:
            value = '0' + value
        return value
    
    def makebin(value,size=32):
        value = bin(value)[2:]
        while len(value)<size:
            value = '0' + value
        return value
    
    def ROL(value,n):
        return (value << n) | (value >> 32-n)
    
    def little_end(string,base = 16):
        t = ''
        if base == 2:
            s= 8
        if base == 16:
            s = 2
        for x in range(len(string)/s):
            t = string[s*x:s*(x+1)] + t
        return t
    
    def F(x,y,z,round):
        if round<16:
            return x ^ y ^ z
        elif 16<=round<32:
            return (x & y) | (~x & z)
        elif 32<=round<48:
            return (x | ~y) ^ z
        elif 48<=round<64:
            return (x & z) | (y & ~z)
        elif 64<=round:
            return x ^ (y | ~z)
    
    def RIPEMD160(data):
    
    # constants
        h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE;h3 = 0x10325476; h4 = 0xC3D2E1F0
    
        k  = [0, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]
        kk = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9,0]
        s =     [   11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,
                7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,
                11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,
                11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,
                9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]
        ss=     [   8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,
                9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,
                9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,
                15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,
                8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]
        r= range(16) + [    7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
                    3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
                    1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
                    4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]
        rr =    [   5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
                6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
                15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
                8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
                12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]   
    
        # md4 padding + preprocessing
        temp = ''
        for x in data:
            temp += makebin(int(x,16),4)
        length = len(temp)%2**64
        temp +='1'
        while len(temp)%512!=448:
            temp+='0'
        input = temp
        temp = makebin(length,64)
        bit_length=''
        for x in range(len(input)/32):
            bit_length += little_end(temp[32*x:32*(x+1)],2)
        input += bit_length[32:]+bit_length[:32]
        t = len(input)/512
        # the rounds
        for i in range(t):
    
                # i called the parallel round variables 2x the other round variable: a -> aa
            a = aa = h0; b = bb = h1; c = cc = h2; d = dd = h3; e = ee = h4
            X = input[512*i:512*(i+1)]
            X = [int(little_end(X[32*x:32*(x+1)],2),2) for x in range(16)]
            for j in range(80):
                T = (ROL((a+ F(b, c, d, j) + X[r[j]] + k[j/16])%2**32,s[j])+e)%2**32
                c = ROL(c, 10)%2**32
                a = e; e = d; d = c; c = b; b = T
                T = (ROL((aa+ F(bb,cc,dd,79-j) + X[rr[j]] + kk[j/16] )%2**32,ss[j])+ee)%2**32
                cc = ROL(cc,10)%2**32
                aa = ee; ee = dd; dd = cc; cc = bb; bb = T
            T  = (h1+c+dd)%2**32
            h1 = (h2+d+ee)%2**32
            h2 = (h3+e+aa)%2**32
            h3 = (h4+a+bb)%2**32
            h4 = (h0+b+cc)%2**32
            h0 = T
        return little_end(makehex(h0))+little_end(makehex(h1))+little_end(makehex(h2))+little_end(makehex(h3))+little_end(makehex(h4))
    data = RIPEMD160('')
    print data,data =='9c1185a5c5e9fc54612808977ee8f548b2258d31'
    
11

在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,当用户点击一个按钮时,我们希望程序能够做出反应。这个过程就叫做“事件处理”。

事件处理的基本思路是:我们先定义一个“事件”,然后告诉程序在这个事件发生时应该执行什么样的操作。比如,当用户点击按钮时,我们可以让程序弹出一个消息框,显示“按钮被点击了!”

为了实现这个功能,我们通常会使用一些编程语言提供的工具和方法。不同的编程语言可能有不同的写法,但大体上都是围绕着“监听事件”和“响应事件”这两个步骤来进行的。

总之,事件处理就是让程序能够对用户的操作做出反应,从而提高用户体验。通过合理的事件处理,我们可以让程序变得更加智能和友好。

>>> import hashlib
>>> data = ''
>>> hashlib.new('ripemd160', data).hexdigest()
'9c1185a5c5e9fc54612808977ee8f548b2258d31'

撰写回答