MD5 hash - help
So im trying to program a md5 hash algoritham in C in as simple way as possible , but i just cant get the right result, so if anyone has the time and the pacience to go thrugh my code.
the algoritham is working but i just cant seem to get the right md5 sum
since im simplyfying it(this is my first crack at such a thing), the algorithm is only taking 64byte of data and returning a pointer to hash
typedef unsigned int INT ;
unsigned int t[] = {
0xd76aa478L, /* 1 */
.
.
.
.
the sinus results copied from the net
.
.
.
0xbd3af235L, /* 62 */
0x2ad7d2bbL, /* 63 */
0xeb86d391L /* 64 */
};
unsigned int r[] = { 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
};
unsigned int leftrotate(INT x,INT c){
return (x << c) | (x >> (32-c));
}
unsigned char * md5(unsigned char *input){
unsigned char buff[64];
INT len=strlen((char *)input),w[16],stat[4],f,a,b,c,d,g,i,j,temp;
bzero((char *)buff,sizeof(buff));
for(i=0;i<len && i<59;i++){
buff[i]=input[i];
}
if(len<59){ buff[len]=0x80; len*=8;}
else { buff[59]=0x80; len=59*8; }
for(i=0;i<4;i++){
buff[i+60]=len >> (24 - i*8);
}
for(i=0,j=0;i<16;i++,j+=4){
w[i]=0;
w[i]=(((INT)buff[j]<< 24) | ((INT)buff[j+1]<<16) | ((INT)buff[j+2] << 8) | ((INT)buff[j+3]));
}
stat[0]=0x01234567;
stat[1]=0x89abcdef;
stat[2]=0xfedcba98;
stat[3]=0x76543210;
a=stat[0];
b=stat[1];
c=stat[2];
d=stat[3];
for(i=0;i<64;i++){
if (0 <= i && i<= 15 ){
f = (b & c) | ((~ b) & d);
g = i;
}else if (16 <= i && i<= 31){
f = (d & b) | ((~ d) & c);
g = (5*i + 1) % 16;
}else if (32 <= i && i<= 47){
f = b ^ c ^ d;
g = (3*i + 5) % 16;
}else if (48 <= i && i<= 63){
f = c ^ (b | (~ d));
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + leftrotate((a + f + t[i] + w[g]) , r[i]);
a = temp;
}
stat[0]=a + stat[0];
stat[1]=b + stat[1];
stat[2]=c + stat[2];
stat[3]=d + stat[3];
for(i=0;i<4;i++){
printf("%02x",stat[i]);
}
return input;
}```
thanks
spyware wrote:
Can you post a diff with your broken code and the new, fixed one?
no problem, i can post the fix, but i really dont wona go throu the mistakes, basiclly the problem was the endian, and while transforming data from int to char and vice versa it got a bit f… up
so anyway here is the working code, you can compere with the code above, to see the mistakes
the function doesnt return anything just prints the hash
typedef unsigned int INT ;
unsigned int t[] = {
0xd76aa478L, /* 1 */
0xe8c7b756L, /* 2 */
0x242070dbL, /* 3 */
0xc1bdceeeL, /* 4 */
0xf57c0fafL, /* 5 */
0x4787c62aL, /* 6 */
0xa8304613L, /* 7 */
0xfd469501L, /* 8 */
0x698098d8L, /* 9 */
0x8b44f7afL, /* 10 */
0xffff5bb1L, /* 11 */
0x895cd7beL, /* 12 */
0x6b901122L, /* 13 */
0xfd987193L, /* 14 */
0xa679438eL, /* 15 */
0x49b40821L, /* 16 */
0xf61e2562L, /* 17 */
0xc040b340L, /* 18 */
0x265e5a51L, /* 19 */
0xe9b6c7aaL, /* 20 */
0xd62f105dL, /* 21 */
0x02441453L, /* 22 */
0xd8a1e681L, /* 23 */
0xe7d3fbc8L, /* 24 */
0x21e1cde6L, /* 25 */
0xc33707d6L, /* 26 */
0xf4d50d87L, /* 27 */
0x455a14edL, /* 28 */
0xa9e3e905L, /* 29 */
0xfcefa3f8L, /* 30 */
0x676f02d9L, /* 31 */
0x8d2a4c8aL, /* 32 */
0xfffa3942L, /* 33 */
0x8771f681L, /* 34 */
0x6d9d6122L, /* 35 */
0xfde5380cL, /* 36 */
0xa4beea44L, /* 37 */
0x4bdecfa9L, /* 38 */
0xf6bb4b60L, /* 39 */
0xbebfbc70L, /* 40 */
0x289b7ec6L, /* 41 */
0xeaa127faL, /* 42 */
0xd4ef3085L, /* 43 */
0x04881d05L, /* 44 */
0xd9d4d039L, /* 45 */
0xe6db99e5L, /* 46 */
0x1fa27cf8L, /* 47 */
0xc4ac5665L, /* 48 */
0xf4292244L, /* 49 */
0x432aff97L, /* 50 */
0xab9423a7L, /* 51 */
0xfc93a039L, /* 52 */
0x655b59c3L, /* 53 */
0x8f0ccc92L, /* 54 */
0xffeff47dL, /* 55 */
0x85845dd1L, /* 56 */
0x6fa87e4fL, /* 57 */
0xfe2ce6e0L, /* 58 */
0xa3014314L, /* 59 */
0x4e0811a1L, /* 60 */
0xf7537e82L, /* 61 */
0xbd3af235L, /* 62 */
0x2ad7d2bbL, /* 63 */
0xeb86d391L /* 64 */
};
unsigned int r[] = { 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
};
unsigned int leftrotate(INT x,INT c){
return (x << c) | (x >> (32-c));
}
unsigned char * md5(unsigned char *input){
unsigned char output[16],buff[64];
INT len=strlen((char *)input),w[16],stat[4],f,a,b,c,d,g,i,j,temp;
bzero((char *)buff,sizeof(buff));
for(i=0;i<len && i<55;i++){
buff[i]=input[i];
}
if(len<55){ buff[len]=0x80; len*=8;}
else { buff[55]=0x80; len=55*8; }
for(i=0;i<4;i++){
buff[i+56]=len >> (i*8);
}
for(i=0,j=0;i<16;i++,j+=4){
w[i]=0;
w[i]=(((INT)buff[j]) | ((INT)buff[j+1]<<8) | ((INT)buff[j+2] << 16) | ((INT)buff[j+3]<<24));
}
stat[0]=0x67452301;
stat[1]=0xefcdab89;
stat[2]=0x98badcfe;
stat[3]=0x10325476;
a=stat[0];
b=stat[1];
c=stat[2];
d=stat[3];
for(i=0;i<64;i++){
if (0 <= i && i<= 15 ){
f = (b & c) | ((~ b) & d);
g = i;
}else if (16 <= i && i<= 31){
f = (d & b) | ((~ d) & c);
g = (5*i + 1) % 16;
}else if (32 <= i && i<= 47){
f = b ^ c ^ d;
g = (3*i + 5) % 16;
}else if (48 <= i && i<= 63){
f = c ^ (b | (~ d));
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + leftrotate((a + f + t[i] + w[g]) , r[i]);
a = temp;
}
stat[0]=a + stat[0];
stat[1]=b + stat[1];
stat[2]=c + stat[2];
stat[3]=d + stat[3];
for(i=0,j=0;j<16;i++,j+=4){
output[j]=(unsigned char)( stat[i]);
output[j+1]=(unsigned char)( stat[i]>>8);
output[j+2]=(unsigned char)( stat[i]>>16);
output[j+3]=(unsigned char)(stat[i]>>24);
}
bzero(out,sizeof(out));
for(i=0,j=0;j<16;i+=2,j++){
printf(&out[i],"%02x",output[j]);
}
return ;
}
keep in mind this only works with string up to 55 bytes, it cant give you a hash of a file , it just gives you a hash of a single string
but you can extend it to work with all the sizes, it will just take a small amount of coding