Hi list.
I started playing with a simple implementation of MD5 (basically straight from the wiki page)
When the implementation produce the correct output, I did some timing for fun and also
To my astonishment I discovered that the code was slower when native compiled.
I am using R15B01 on mac. Can this be true? And in this case why?
Note that I do not care to optimize the implementation it self! I am more interested why
the native compiler produce slower code on this example.
-module(md5).
-compile(export_all).
k(I) when I >= 0, I < 64 -> %% may construct table!
trunc(abs(math:sin(I+1)) * (1 bsl 32)).
r(I) when I >= 0, I < 64 ->
element(I+1,
{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}).
hex(Bin) ->
[ element(H+1,{$0,$1,$2,$3,$4,$5,$6,$7,$8,$9,$a,$b,$c,$d,$e,$f}) ||
<<H:4>> <= Bin ].
md5_test(Input) ->
{hex(md5(Input)), hex(erlang:md5(Input))}.
md5(List) when is_list(List) ->
md5(list_to_binary(List));
md5(Bits) when is_bitstring(Bits) ->
Length = bit_size(Bits),
Pad = (512 - (Length+1+64) rem 512) rem 512,
Bits1 = <<Bits/bitstring,1:1,0:Pad,Length:64/little>>,
md5(Bits1,16#67452301,16#efcdab89,16#98badcfe,16#10325476).
md5(<<>>, H0,H1,H2,H3) ->
<<H0:32/little,H1:32/little,H2:32/little,H3:32/little>>;
md5(Bits,H0,H1,H2,H3) ->
<<Chunk:64/binary, Rest/binary>> = Bits,
W = list_to_tuple([ X || <<X:32/little>> <= Chunk ]),
{A,B,C,D} = md5_(0, W, H0, H1, H2, H3),
md5(Rest, H0+A,H1+B,H2+C,H3+D).
md5_(I, W, A, B, C, D) when I < 16 ->
F = (B band C) bor ((bnot B) band D),
G = I,
R = rotate(A+F+k(I)+element(G+1,W), r(I)),
md5_(I+1,W,D,B+R,B,C);
md5_(I, W, A, B, C, D) when I < 32 ->
F = (D band B) bor ((bnot D) band C),
G = (5*I + 1) rem 16,
R = rotate(A+F+k(I)+element(G+1,W), r(I)),
md5_(I+1,W,D,B+R,B,C);
md5_(I, W, A, B, C, D) when I < 48 ->
F = (B bxor C) bxor D,
G = (3*I+5) rem 16,
R = rotate(A+F+k(I)+element(G+1,W), r(I)),
md5_(I+1,W,D,B+R,B,C);
md5_(I, W, A, B, C, D) when I < 64 ->
F = C bxor (B bor (bnot D)),
G = (7*I) rem 16,
R = rotate(A+F+k(I)+element(G+1,W), r(I)),
md5_(I+1,W,D,B+R,B,C);
md5_(64, _W, A, B, C, D) ->
{A,B,C,D}.
rotate(X0, C) ->
X = X0 band 16#ffffffff,
((X bsl C) bor (X bsr (32-C))) band 16#ffffffff.