![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
King of Portal
|
Well I recently made a small md5 hash calculator program and posted it on the finished projects section. However, upon reading some replies Sane said that perhaps I should try implementing it myself, and so I did. However, I'm unsure why my implementation isn't working. Here's the code, it's two java classes, a driver called MD5Test and the MD5 class:
MD5.java public class MD5
{
private static final int[] T = new int[64];
public MD5()
{
int i = 0;
T[i++] = 0xd76aa478;
T[i++] = 0xe8c7b756;
T[i++] = 0x242070db;
T[i++] = 0xc1bdceee;
T[i++] = 0xf57c0faf;
T[i++] = 0x4787c62a;
T[i++] = 0xa8304613;
T[i++] = 0xfd469501;
T[i++] = 0x698098d8;
T[i++] = 0x8b44f7af;
T[i++] = 0xffff5bb1;
T[i++] = 0x895cd7be;
T[i++] = 0x6b901122;
T[i++] = 0xfd987193;
T[i++] = 0xa679438e;
T[i++] = 0x49b40821;
T[i++] = 0xf61e2562;
T[i++] = 0xc040b340;
T[i++] = 0x265e5a51;
T[i++] = 0xe9b6c7aa;
T[i++] = 0xd62f105d;
T[i++] = 0x2441453;
T[i++] = 0xd8a1e681;
T[i++] = 0xe7d3fbc8;
T[i++] = 0x21e1cde6;
T[i++] = 0xc33707d6;
T[i++] = 0xf4d50d87;
T[i++] = 0x455a14ed;
T[i++] = 0xa9e3e905;
T[i++] = 0xfcefa3f8;
T[i++] = 0x676f02d9;
T[i++] = 0x8d2a4c8a;
T[i++] = 0xfffa3942;
T[i++] = 0x8771f681;
T[i++] = 0x6d9d6122;
T[i++] = 0xfde5380c;
T[i++] = 0xa4beea44;
T[i++] = 0x4bdecfa9;
T[i++] = 0xf6bb4b60;
T[i++] = 0xbebfbc70;
T[i++] = 0x289b7ec6;
T[i++] = 0xeaa127fa;
T[i++] = 0xd4ef3085;
T[i++] = 0x4881d05;
T[i++] = 0xd9d4d039;
T[i++] = 0xe6db99e5;
T[i++] = 0x1fa27cf8;
T[i++] = 0xc4ac5665;
T[i++] = 0xf4292244;
T[i++] = 0x432aff97;
T[i++] = 0xab9423a7;
T[i++] = 0xfc93a039;
T[i++] = 0x655b59c3;
T[i++] = 0x8f0ccc92;
T[i++] = 0xffeff47d;
T[i++] = 0x85845dd1;
T[i++] = 0x6fa87e4f;
T[i++] = 0xfe2ce6e0;
T[i++] = 0xa3014314;
T[i++] = 0x4e0811a1;
T[i++] = 0xf7537e82;
T[i++] = 0xbd3af235;
T[i++] = 0x2ad7d2bb;
T[i++] = 0xeb86d391;
}
public String hash()
{
int A = 0x67452301;
int B = 0xefcdab89;
int C = 0x98badcfe;
int D = 0x10325476;
int[] M = new int[16];
int[] X = new int[16];
// A message of no length
// Starts here
M[0] = 0x80000000;
for(int i = 1; i < M.length; i++)
{
M[i] = 0;
}
// Ends here
for(int i = 0; i < M.length / 16; i++)
{
for(int j = 0; j < 16; j++)
{
X[j] = M[i * 16 + j];
}
int AA = A;
int BB = B;
int CC = C;
int DD = D;
A = round1(A, B, C, D, X[0], 7, 1 - 1);
D = round1(D, A, B, C, X[1], 12, 2 - 1);
C = round1(C, D, A, B, X[2], 17, 3 - 1);
B = round1(B, C, D, A, X[3], 22, 4 - 1);
A = round1(A, B, C, D, X[4], 7, 5 - 1);
D = round1(D, A, B, C, X[5], 12, 6 - 1);
C = round1(C, D, A, B, X[6], 17, 7 - 1);
B = round1(B, C, D, A, X[7], 22, 8 - 1);
A = round1(A, B, C, D, X[8], 7, 9 - 1 );
D = round1(D, A, B, C, X[9], 12, 10 - 1);
C = round1(C, D, A, B, X[10], 17, 11 - 1);
B = round1(B, C, D, A, X[11], 22, 12 - 1);
A = round1(A, B, C, D, X[12], 7, 13 - 1);
D = round1(D, A, B, C, X[13], 12, 14 - 1);
C = round1(C, D, A, B, X[14], 17, 15 - 1);
B = round1(B, C, D, A, X[15], 22, 16 - 1);
A = round2(A, B, C, D, X[1], 5, 17 - 1);
D = round2(D, A, B, C, X[6], 9, 18 - 1);
C = round2(C, D, A, B, X[11], 14, 19 - 1);
B = round2(B, C, D, A, X[0], 20, 20 - 1);
A = round2(A, B, C, D, X[5], 5, 21 - 1);
D = round2(D, A, B, C, X[10], 9, 22 - 1);
C = round2(C, D, A, B, X[15], 14, 23 - 1);
B = round2(B, C, D, A, X[4], 20, 24 - 1);
A = round2(A, B, C, D, X[9], 5, 25 - 1);
D = round2(D, A, B, C, X[14], 9, 26 - 1);
C = round2(C, D, A, B, X[3], 14, 27 - 1);
B = round2(B, C, D, A, X[8], 20, 28 - 1);
A = round2(A, B, C, D, X[13], 5, 29 - 1);
D = round2(D, A, B, C, X[2], 9, 30 - 1);
C = round2(C, D, A, B, X[7], 14, 31 - 1);
B = round2(B, C, D, A, X[12], 20, 32 - 1);
A = round3(A, B, C, D, X[5], 4, 33 - 1);
D = round3(D, A, B, C, X[8], 11, 34 - 1);
C = round3(C, D, A, B, X[11], 16, 35 - 1);
B = round3(B, C, D, A, X[14], 23, 36 - 1);
A = round3(A, B, C, D, X[1], 4, 37 - 1);
D = round3(D, A, B, C, X[4], 11, 38 - 1);
C = round3(C, D, A, B, X[7], 16, 39 - 1);
B = round3(B, C, D, A, X[10], 23, 40 - 1);
A = round3(A, B, C, D, X[13], 4, 41 - 1);
D = round3(D, A, B, C, X[0], 11, 42 - 1);
C = round3(C, D, A, B, X[3], 16, 43 - 1);
B = round3(B, C, D, A, X[6], 23, 44 - 1);
A = round3(A, B, C, D, X[9], 4, 45 - 1);
D = round3(D, A, B, C, X[12], 11, 46 - 1);
C = round3(C, D, A, B, X[15], 16, 47 - 1);
B = round3(B, C, D, A, X[2], 23, 48 - 1);
A = round4(A, B, C, D, X[0], 6, 49 - 1);
D = round4(D, A, B, C, X[7], 10, 50 - 1);
C = round4(C, D, A, B, X[14], 15, 51 - 1);
B = round4(B, C, D, A, X[5], 21, 52 - 1);
A = round4(A, B, C, D, X[12], 6, 53 - 1);
D = round4(D, A, B, C, X[3], 10, 54 - 1);
C = round4(C, D, A, B, X[10], 15, 55 - 1);
B = round4(B, C, D, A, X[1], 21, 56 - 1);
A = round4(A, B, C, D, X[8], 6, 57 - 1);
D = round4(D, A, B, C, X[15], 10, 58 - 1);
C = round4(C, D, A, B, X[6], 15, 59 - 1);
B = round4(B, C, D, A, X[13], 21, 60 - 1);
A = round4(A, B, C, D, X[4], 6, 61 - 1);
D = round4(D, A, B, C, X[11], 10, 62 - 1);
C = round4(C, D, A, B, X[2], 15, 63 - 1);
B = round4(B, C, D, A, X[9], 21, 64 - 1);
A += AA;
B += BB;
C += CC;
D += DD;
}
return Integer.toHexString(A) + Integer.toHexString(B) + Integer.toHexString(C) + Integer.toHexString(D);
}
private int round1(int a, int b, int c, int d, int x, int s, int i)
{
return b + lShiftRotate((a + F(b, c, d) + x + T[i]), s);
}
private int round2(int a, int b, int c, int d, int x, int s, int i)
{
return b + lShiftRotate((a + G(b, c, d) + x + T[i]), s);
}
private int round3(int a, int b, int c, int d, int x, int s, int i)
{
return b + lShiftRotate((a + H(b, c, d) + x + T[i]), s);
}
private int round4(int a, int b, int c, int d, int x, int s, int i)
{
return b + lShiftRotate((a + I(b, c, d) + x + T[i]), s);
}
private int F(int X, int Y, int Z)
{
return X & Y | ~X & Z;
}
private int G(int X, int Y, int Z)
{
return X & Z | Y & ~Z;
}
private int H(int X, int Y, int Z)
{
return X ^ Y ^ Z;
}
private int I(int X, int Y, int Z)
{
return Y ^ (X | ~Z);
}
public static int lShiftRotate(int x, int y)
{
int mask = 0x80000000;
for(int i = 0; i < y; i++)
{
if((x & mask) == 0)
{
x = x << 1;
}
else
{
x = (x << 1) + 1;
}
}
return x;
}
}public class MD5Test
{
public static void main(String[] args)
{
MD5 message = new MD5();
System.out.println(message.hash());
}
}P.S. As stated in the RFC the hash for a string of "" should be MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#2 |
|
King of Portal
|
uhh... yeah I typed in those values for nothing in the constructor 'cause I actually figured out how to work the formula, anyways here's how to determine the values of T according to the stipulation in the RFC:
public MD5()
{
for(int i = 0; i < T.length; i++)
{
double temp = Math.abs(Math.sin(i + 1)) * Math.pow(2, 32);
if(temp > Math.pow(2, 32) / 2 - 1)
{
T[i] = (int)Math.floor(temp - Math.pow(2, 32));
}
else
{
T[i] = (int)Math.floor(temp);
}
}
} |
|
|
|
|
|
#3 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
No wonder pirates are grim.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#4 |
|
King of Portal
|
The C is a harsh mistress. That's why we drink plenty of Java. ahahaha
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#5 | |
|
Hobbyist Programmer
|
Quote:
![]()
__________________
Pain is just weakness leaving the body.
|
|
|
|
|
|
|
#6 |
|
King of Portal
|
Breakthrough!
yes I discovered what the problem was with my code. As it turns out the implementation was correct there were no little tiny errors or anything. However, what happens is that Rivest fails to mention in the RFC that input is assumed to be in a little-endian format and therefore needs to be decoded into big-endian format. Furthermore, the outputs A, B, C, and D are in little-endian format and need to be output into big-endian format. Why did he do this? I have no idea but as far as I'm concerned the man's an idiot, especially since it just seems to be wasting clock cycles. In my code you'll note the two major changes: the array value's inital value M[0] is now 0x00000080 instead of 0x80000000 and I added a function called encode which transforms from little-endian into big-endian. This is also why the values of A, B, C, and D, when initialized look mirrored to how they are written in the RFC. Here's the updated MD5 class
MD5.java import java.lang.Math;
public class MD5
{
private static int[] T = new int[64];
public MD5()
{
for(int i = 0; i < T.length; i++)
{
double temp = Math.abs(Math.sin(i + 1)) * Math.pow(2, 32);
if(temp > Math.pow(2, 32) / 2 - 1)
{
T[i] = (int)Math.floor(temp - Math.pow(2, 32));
}
else
{
T[i] = (int)Math.floor(temp);
}
}
}
public String hash()
{
int A = 0x67452301;
int B = 0xefcdab89;
int C = 0x98badcfe;
int D = 0x10325476;
int[] M = new int[16];
int[] X = new int[16];
// A message of no length
// Starts here
// This was reversed because the input is supposed to come in little-endian format
// while computations are performed in a big-endian style
M[0] = 0x00000080;
for(int i = 1; i < M.length; i++)
{
M[i] = 0;
}
// Ends here
for(int i = 0; i < M.length / X.length; i++)
{
for(int j = 0; j < X.length; j++)
{
X[j] = M[i * 16 + j];
}
int AA = A;
int BB = B;
int CC = C;
int DD = D;
A = round1(A, B, C, D, X[0], 7, 1 - 1);
D = round1(D, A, B, C, X[1], 12, 2 - 1);
C = round1(C, D, A, B, X[2], 17, 3 - 1);
B = round1(B, C, D, A, X[3], 22, 4 - 1);
A = round1(A, B, C, D, X[4], 7, 5 - 1);
D = round1(D, A, B, C, X[5], 12, 6 - 1);
C = round1(C, D, A, B, X[6], 17, 7 - 1);
B = round1(B, C, D, A, X[7], 22, 8 - 1);
A = round1(A, B, C, D, X[8], 7, 9 - 1 );
D = round1(D, A, B, C, X[9], 12, 10 - 1);
C = round1(C, D, A, B, X[10], 17, 11 - 1);
B = round1(B, C, D, A, X[11], 22, 12 - 1);
A = round1(A, B, C, D, X[12], 7, 13 - 1);
D = round1(D, A, B, C, X[13], 12, 14 - 1);
C = round1(C, D, A, B, X[14], 17, 15 - 1);
B = round1(B, C, D, A, X[15], 22, 16 - 1);
A = round2(A, B, C, D, X[1], 5, 17 - 1);
D = round2(D, A, B, C, X[6], 9, 18 - 1);
C = round2(C, D, A, B, X[11], 14, 19 - 1);
B = round2(B, C, D, A, X[0], 20, 20 - 1);
A = round2(A, B, C, D, X[5], 5, 21 - 1);
D = round2(D, A, B, C, X[10], 9, 22 - 1);
C = round2(C, D, A, B, X[15], 14, 23 - 1);
B = round2(B, C, D, A, X[4], 20, 24 - 1);
A = round2(A, B, C, D, X[9], 5, 25 - 1);
D = round2(D, A, B, C, X[14], 9, 26 - 1);
C = round2(C, D, A, B, X[3], 14, 27 - 1);
B = round2(B, C, D, A, X[8], 20, 28 - 1);
A = round2(A, B, C, D, X[13], 5, 29 - 1);
D = round2(D, A, B, C, X[2], 9, 30 - 1);
C = round2(C, D, A, B, X[7], 14, 31 - 1);
B = round2(B, C, D, A, X[12], 20, 32 - 1);
A = round3(A, B, C, D, X[5], 4, 33 - 1);
D = round3(D, A, B, C, X[8], 11, 34 - 1);
C = round3(C, D, A, B, X[11], 16, 35 - 1);
B = round3(B, C, D, A, X[14], 23, 36 - 1);
A = round3(A, B, C, D, X[1], 4, 37 - 1);
D = round3(D, A, B, C, X[4], 11, 38 - 1);
C = round3(C, D, A, B, X[7], 16, 39 - 1);
B = round3(B, C, D, A, X[10], 23, 40 - 1);
A = round3(A, B, C, D, X[13], 4, 41 - 1);
D = round3(D, A, B, C, X[0], 11, 42 - 1);
C = round3(C, D, A, B, X[3], 16, 43 - 1);
B = round3(B, C, D, A, X[6], 23, 44 - 1);
A = round3(A, B, C, D, X[9], 4, 45 - 1);
D = round3(D, A, B, C, X[12], 11, 46 - 1);
C = round3(C, D, A, B, X[15], 16, 47 - 1);
B = round3(B, C, D, A, X[2], 23, 48 - 1);
A = round4(A, B, C, D, X[0], 6, 49 - 1);
D = round4(D, A, B, C, X[7], 10, 50 - 1);
C = round4(C, D, A, B, X[14], 15, 51 - 1);
B = round4(B, C, D, A, X[5], 21, 52 - 1);
A = round4(A, B, C, D, X[12], 6, 53 - 1);
D = round4(D, A, B, C, X[3], 10, 54 - 1);
C = round4(C, D, A, B, X[10], 15, 55 - 1);
B = round4(B, C, D, A, X[1], 21, 56 - 1);
A = round4(A, B, C, D, X[8], 6, 57 - 1);
D = round4(D, A, B, C, X[15], 10, 58 - 1);
C = round4(C, D, A, B, X[6], 15, 59 - 1);
B = round4(B, C, D, A, X[13], 21, 60 - 1);
A = round4(A, B, C, D, X[4], 6, 61 - 1);
D = round4(D, A, B, C, X[11], 10, 62 - 1);
C = round4(C, D, A, B, X[2], 15, 63 - 1);
B = round4(B, C, D, A, X[9], 21, 64 - 1);
A += AA;
B += BB;
C += CC;
D += DD;
}
return Integer.toHexString(encode(A)) + Integer.toHexString(encode(B)) + Integer.toHexString(encode(C)) + Integer.toHexString(encode(D));
}
private int round1(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + F(b, c, d) + x + T[i]), s);
}
private int round2(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + G(b, c, d) + x + T[i]), s);
}
private int round3(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + H(b, c, d) + x + T[i]), s);
}
private int round4(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + I(b, c, d) + x + T[i]), s);
}
private int F(int X, int Y, int Z)
{
return X & Y | ~X & Z;
}
private int G(int X, int Y, int Z)
{
return X & Z | Y & ~Z;
}
private int H(int X, int Y, int Z)
{
return X ^ Y ^ Z;
}
private int I(int X, int Y, int Z)
{
return Y ^ (X | ~Z);
}
// This method converts an input from little-endian into big-endian
private int encode(int x)
{
int mask[] = new int[4];
mask[0] = 0xff000000;
mask[1] = 0x00ff0000;
mask[2] = 0x0000ff00;
mask[3] = 0x000000ff;
return Integer.rotateRight(x & mask[0], 24) + Integer.rotateRight(x & mask[1], 8) + Integer.rotateLeft(x & mask[2], 8) + Integer.rotateLeft(x & mask[3], 24);
}
}
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#7 |
|
Programming Guru
![]() ![]() ![]() |
[aside]
"Pirates rule!" Today was deemed "Pirate's Day" by my employer. The upper management dressed up as pirates and came around the offices (aka Cubevile, aka Dilbertville) handing out "stolen treasure".... I threw all of the crap aside to try and find the gold, but no gold and no check... Management needs to learn how to code, they have too much free time on their hands... bah. [/aside]
__________________
http://jasonpowers.net "There are a thousand hacking at the branches of evil to one who is striking at the root." |
|
|
|
|
|
#8 |
|
King of Portal
|
Well I got it to accept bytes, so to all you programmers out there please try as many different strings as you can come up with and lemme know if they produce the wrong output, assuming you care to that is. I tried it out with Rivest's test suite and it worked fine and with some of my own so I'm gonna say it's working. Here are the two classes again:
MD5.java import java.lang.Math;
public class MD5
{
private int[] T = new int[64];
private int A = 0x67452301;
private int B = 0xefcdab89;
private int C = 0x98badcfe;
private int D = 0x10325476;
private long bytesTransferred = 0;
private int bytesSwitch = 0;
private int[] X;
private int entrySwitch = 0;
private int transferredWord = 0;
public MD5()
{
for(int i = 0; i < T.length; i++)
{
double temp = Math.abs(Math.sin(i + 1)) * Math.pow(2, 32);
if(temp > Math.pow(2, 32) / 2 - 1)
{
T[i] = (int)Math.floor(temp - Math.pow(2, 32));
}
else
{
T[i] = (int)Math.floor(temp);
}
}
X = new int[16];
}
public void update(byte chunk)
{
bytesTransferred++;
bytesSwitch++;
int temp = 0;
switch(bytesSwitch)
{
case 1:
temp = chunk & 0x000000ff;
break;
case 2:
temp = chunk & 0x000000ff;
temp = temp << 8;
break;
case 3:
temp = chunk & 0x000000ff;
temp = temp << 16;
break;
case 4:
temp = chunk & 0x000000ff;
temp = temp << 24;
break;
}
transferredWord = transferredWord ^ temp;
if(bytesSwitch == 4)
{
bytesSwitch = 0;
X[entrySwitch] = transferredWord;
entrySwitch++;
transferredWord = 0;
}
// int[] M = new int[16];
// A message of no length
// Starts here
// This was reversed because the input is supposed to come in little-endian format
// while computations are performed in a big-endian style
// M[0] = 0x80636261; // "abc"
// M[1] = 0;
// M[2] = 0;
// M[3] = 0;
// M[4] = 0;
// M[5] = 0;
// M[6] = 0;
// M[7] = 0;
// M[8] = 0;
// M[9] = 0;
// M[10] = 0;
// M[11] = 0;
// M[12] = 0;
// M[13] = 0;
// M[14] = 0x00000018;
// M[15] = 0x00000000;
// Ends here
// for(int i = 0; i < M.length / X.length; i++)
// {
// for(int j = 0; j < X.length; j++)
// {
// X[j] = M[i * 16 + j];
// }
if(entrySwitch == 16)
{
entrySwitch = 0;
int AA = A;
int BB = B;
int CC = C;
int DD = D;
A = round1(A, B, C, D, X[0], 7, 1 - 1);
D = round1(D, A, B, C, X[1], 12, 2 - 1);
C = round1(C, D, A, B, X[2], 17, 3 - 1);
B = round1(B, C, D, A, X[3], 22, 4 - 1);
A = round1(A, B, C, D, X[4], 7, 5 - 1);
D = round1(D, A, B, C, X[5], 12, 6 - 1);
C = round1(C, D, A, B, X[6], 17, 7 - 1);
B = round1(B, C, D, A, X[7], 22, 8 - 1);
A = round1(A, B, C, D, X[8], 7, 9 - 1 );
D = round1(D, A, B, C, X[9], 12, 10 - 1);
C = round1(C, D, A, B, X[10], 17, 11 - 1);
B = round1(B, C, D, A, X[11], 22, 12 - 1);
A = round1(A, B, C, D, X[12], 7, 13 - 1);
D = round1(D, A, B, C, X[13], 12, 14 - 1);
C = round1(C, D, A, B, X[14], 17, 15 - 1);
B = round1(B, C, D, A, X[15], 22, 16 - 1);
A = round2(A, B, C, D, X[1], 5, 17 - 1);
D = round2(D, A, B, C, X[6], 9, 18 - 1);
C = round2(C, D, A, B, X[11], 14, 19 - 1);
B = round2(B, C, D, A, X[0], 20, 20 - 1);
A = round2(A, B, C, D, X[5], 5, 21 - 1);
D = round2(D, A, B, C, X[10], 9, 22 - 1);
C = round2(C, D, A, B, X[15], 14, 23 - 1);
B = round2(B, C, D, A, X[4], 20, 24 - 1);
A = round2(A, B, C, D, X[9], 5, 25 - 1);
D = round2(D, A, B, C, X[14], 9, 26 - 1);
C = round2(C, D, A, B, X[3], 14, 27 - 1);
B = round2(B, C, D, A, X[8], 20, 28 - 1);
A = round2(A, B, C, D, X[13], 5, 29 - 1);
D = round2(D, A, B, C, X[2], 9, 30 - 1);
C = round2(C, D, A, B, X[7], 14, 31 - 1);
B = round2(B, C, D, A, X[12], 20, 32 - 1);
A = round3(A, B, C, D, X[5], 4, 33 - 1);
D = round3(D, A, B, C, X[8], 11, 34 - 1);
C = round3(C, D, A, B, X[11], 16, 35 - 1);
B = round3(B, C, D, A, X[14], 23, 36 - 1);
A = round3(A, B, C, D, X[1], 4, 37 - 1);
D = round3(D, A, B, C, X[4], 11, 38 - 1);
C = round3(C, D, A, B, X[7], 16, 39 - 1);
B = round3(B, C, D, A, X[10], 23, 40 - 1);
A = round3(A, B, C, D, X[13], 4, 41 - 1);
D = round3(D, A, B, C, X[0], 11, 42 - 1);
C = round3(C, D, A, B, X[3], 16, 43 - 1);
B = round3(B, C, D, A, X[6], 23, 44 - 1);
A = round3(A, B, C, D, X[9], 4, 45 - 1);
D = round3(D, A, B, C, X[12], 11, 46 - 1);
C = round3(C, D, A, B, X[15], 16, 47 - 1);
B = round3(B, C, D, A, X[2], 23, 48 - 1);
A = round4(A, B, C, D, X[0], 6, 49 - 1);
D = round4(D, A, B, C, X[7], 10, 50 - 1);
C = round4(C, D, A, B, X[14], 15, 51 - 1);
B = round4(B, C, D, A, X[5], 21, 52 - 1);
A = round4(A, B, C, D, X[12], 6, 53 - 1);
D = round4(D, A, B, C, X[3], 10, 54 - 1);
C = round4(C, D, A, B, X[10], 15, 55 - 1);
B = round4(B, C, D, A, X[1], 21, 56 - 1);
A = round4(A, B, C, D, X[8], 6, 57 - 1);
D = round4(D, A, B, C, X[15], 10, 58 - 1);
C = round4(C, D, A, B, X[6], 15, 59 - 1);
B = round4(B, C, D, A, X[13], 21, 60 - 1);
A = round4(A, B, C, D, X[4], 6, 61 - 1);
D = round4(D, A, B, C, X[11], 10, 62 - 1);
C = round4(C, D, A, B, X[2], 15, 63 - 1);
B = round4(B, C, D, A, X[9], 21, 64 - 1);
A += AA;
B += BB;
C += CC;
D += DD;
}
}
public String finish()
{
long fileSize = bytesTransferred * 8; // in bits
byte sizePad[] = new byte[8];
sizePad[0] = (byte)(fileSize & 0x00000000000000ffL);
sizePad[1] = (byte)((fileSize >> 8) & 0x00000000000000ffL);
sizePad[2] = (byte)((fileSize >> 16) & 0x00000000000000ffL);
sizePad[3] = (byte)((fileSize >> 24) & 0x00000000000000ffL);
sizePad[4] = (byte)((fileSize >> 32) & 0x00000000000000ffL);
sizePad[5] = (byte)((fileSize >> 40) & 0x00000000000000ffL);
sizePad[6] = (byte)((fileSize >> 48) & 0x00000000000000ffL);
sizePad[7] = (byte)((fileSize >> 56) & 0x00000000000000ffL);
update((byte)0x80);
long incongruent = bytesTransferred % 64;
if(incongruent < 57)
{
for(long i = incongruent; i < 56; i++)
{
update((byte)0x00);
}
}
else
{
for(long i = incongruent; i < 64; i++)
{
update((byte)0x00);
}
for(int i = 0; i < 56; i++)
{
update((byte)0x00);
}
}
for(int i = 0; i < sizePad.length; i++)
{
update(sizePad[i]);
}
return parseHash();
}
private String parseHash()
{
String part[] = new String[4];
part[0] = Integer.toHexString(encode(A));
part[1] = Integer.toHexString(encode(B));
part[2] = Integer.toHexString(encode(C));
part[3] = Integer.toHexString(encode(D));
for(int j = 0; j < part.length; j++)
{
for(int i = 0; i < 8 - part[j].length(); i++)
{
part[j] = "0" + part[j];
}
}
return part[0] + part[1] + part[2] + part[3];
}
private int round1(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + F(b, c, d) + x + T[i]), s);
}
private int round2(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + G(b, c, d) + x + T[i]), s);
}
private int round3(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + H(b, c, d) + x + T[i]), s);
}
private int round4(int a, int b, int c, int d, int x, int s, int i)
{
return b + Integer.rotateLeft((a + I(b, c, d) + x + T[i]), s);
}
private int F(int X, int Y, int Z)
{
return X & Y | ~X & Z;
}
private int G(int X, int Y, int Z)
{
return X & Z | Y & ~Z;
}
private int H(int X, int Y, int Z)
{
return X ^ Y ^ Z;
}
private int I(int X, int Y, int Z)
{
return Y ^ (X | ~Z);
}
// This method converts an input from little-endian into big-endian
private int encode(int x)
{
int mask[] = new int[4];
mask[0] = 0xff000000;
mask[1] = 0x00ff0000;
mask[2] = 0x0000ff00;
mask[3] = 0x000000ff;
return Integer.rotateRight(x & mask[0], 24) + Integer.rotateRight(x & mask[1], 8) + Integer.rotateLeft(x & mask[2], 8) + Integer.rotateLeft(x & mask[3], 24);
}
}MD5Test.java import java.lang.Math;
public class MD5Test
{
public static void main(String[] args)
{
MD5 message = new MD5();
String foo = new String("a"); // Place test string here
byte bar[] = foo.getBytes();
for(int i = 0; i < bar.length; i++)
{
message.update(bar[i]);
}
System.out.println(message.finish());
}
}
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
|
|
#9 |
|
King of Portal
|
I think I'm going to take Rivest's idea and just make my own algorithm by ignoring the whole little-endian big-endian conversion. It seems like a grandiose waste of processing cycles and of no significant mathematical importance. Onward with pirate recklessness.
__________________
Lo, there do I see my father. 'Lo, there do I see My mother, and my sisters, and my brothers. 'Lo, there do I see The line of my people... Back to the beginning. 'Lo, they do call to me. They bid me take my place among them. In the halls of Valhalla... Where the brave... May live... ...forever.. GrimBB | Mimesis |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Could this get me in trouble? (Reg. Internet Copyright Laws) | Sane | Coder's Corner Lounge | 14 | Jan 26th, 2006 6:14 PM |
| implementation of cpuid and graph in my benchmark programm | chorijan | C++ | 0 | Sep 7th, 2005 6:27 AM |
| ftell() giving me trouble. | 2roll4life7 | C | 5 | Sep 2nd, 2005 12:27 PM |
| Having trouble with an exercise in the C book. | linuxpimp20 | C | 6 | Jul 6th, 2005 7:22 AM |
| Can anyone do this? Im having trouble with classes | jlessard04 | C++ | 10 | Apr 30th, 2005 7:10 PM |