-- -- demo\rosetta\md4.exw -- ==================== -- function r32(atom a) if a<0 then a+=#100000000 end if return remainder(a,#100000000) end function function rol(atom word, integer bits) -- left rotate the bits of a 32-bit number by the specified number of bits word = r32(word) -- trim to a 32-bit uint again return r32(word*power(2,bits))+floor(word/power(2,32-bits)) end function function f(atom x,y,z) return or_bits(and_bits(x,y),and_bits(not_bits(x),z)) end function function g(atom x,y,z) return or_all({r32(and_bits(x,y)),and_bits(x,z),and_bits(y,z)}) end function function h(atom x,y,z) return xor_bits(r32(xor_bits(x,y)),z) end function function md4(sequence data) integer bytes_to_add = 64-remainder(length(data)+9,64) if bytes_to_add=64 then bytes_to_add = 0 end if data = dataP&repeat(0,bytes_to_add)& int_to_bytes(length(data)*8,8) atom a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476 atom m64 = allocate(64,true) integer i for x=1 to length(data)-1 by 64 do poke(m64,data[x..x+63]) sequence z = peek4u({m64,16}) atom a2 = a, b2 = b, c2 = c, d2 = d for i=0 to 12 by 4 do a = rol(a + f(b, c, d) + z[i+1], 3) d = rol(d + f(a, b, c) + z[i+2], 7) c = rol(c + f(d, a, b) + z[i+3], 11) b = rol(b + f(c, d, a) + z[i+4], 19) end for for i=1 to 4 do a = rol(a + g(b, c, d) + z[i+0] + 0x5a827999, 3) d = rol(d + g(a, b, c) + z[i+4] + 0x5a827999, 5) c = rol(c + g(d, a, b) + z[i+8] + 0x5a827999, 9) b = rol(b + g(c, d, a) + z[i+12] + 0x5a827999, 13) end for for j=1 to 4 do i = {1, 3, 2, 4}[j] a = rol(a + h(b, c, d) + z[i+0] + 0x6ed9eba1, 3) d = rol(d + h(a, b, c) + z[i+8] + 0x6ed9eba1, 9) c = rol(c + h(d, a, b) + z[i+4] + 0x6ed9eba1, 11) b = rol(b + h(c, d, a) + z[i+12] + 0x6ed9eba1, 15) end for a = r32(a+a2) b = r32(b+b2) c = r32(c+c2) d = r32(d+d2) end for poke4(m64,{a,b,c,d}) return peek({m64,16}) end function function hexify(sequence s) for i=1 to length(s) do s[i] = sprintf("%02X",s[i]) end for return join(s,"") end function ?hexify(md4("Rosetta Code"))