#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#define SINGLE_ONE_BIT 0x80
#define BLOCK_SIZE 512
#define MOD_SIZE 448
#define APP_SIZE 64
#define BITS 8
// MD5 Chaining Variable
#define A 0x67452301UL
#define B 0xEFCDAB89UL
#define C 0x98BADCFEUL
#define D 0x10325476UL
// Four auxiliary functions
#define F( X, Y, Z ) ( ( (X) & (Y) ) | ( (~(X)) & (Z) ) )
#define G( X, Y, Z ) ( ( (X) & (Z) ) | ( (Y) & (~(Z)) ) )
#define H( X, Y, Z ) ( (X) ^ (Y) ^ (Z) )
#define I( X, Y, Z ) ( (Y) ^ ( (X) | (~(Z)) ) )
// common function
#define LOGIC_SHIFT_LEFT( x, c ) ( ((x) << (c)) | ((x) >> (32 - c)) )
#define FF( a, b, c, d, Mj, s, ti ) \
(a = b + LOGIC_SHIFT_LEFT( ( a + F( b, c, d ) + Mj + ti ), s )) //FF( a, b, c, d, w[0], 7, 0xd76aa478);
#define GG( a, b, c, d, Mj, s, ti ) \
(a = b + LOGIC_SHIFT_LEFT( ( a + G( b, c, d ) + Mj + ti ), s ))
#define HH( a, b, c, d, Mj, s, ti ) \
(a = b + LOGIC_SHIFT_LEFT( ( a + H( b, c, d ) + Mj + ti ), s ))
#define II( a, b, c, d, Mj, s, ti ) \
(a = b + LOGIC_SHIFT_LEFT( ( a + I( b, c, d ) + Mj + ti ), s ))
// Creating own types
#ifdef UINT64
# undef UINT64
#endif
#ifdef UINT32
# undef UINT32
#endif
typedef unsigned __int64 UINT64; //long long 在WIN32中用__int64
typedef unsigned long UINT32; //long 是32位的
typedef struct
{
char * message;
UINT64 length;
}STRING;
// Pre-processin
UINT32 count_padding_bits ( UINT32 length )
{
UINT32 div = length * BITS / BLOCK_SIZE;
UINT32 mod = length * BITS % BLOCK_SIZE;
UINT32 c_bits;
if ( mod == 0 )
c_bits = BLOCK_SIZE;
else
c_bits = ( MOD_SIZE + BLOCK_SIZE - mod ) % BLOCK_SIZE;
return c_bits / BITS;
}
STRING append_padding_bits ( char * argv )
{
UINT32 msg_length = strlen ( argv );
UINT32 bit_length = count_padding_bits ( msg_length );
UINT64 app_length = msg_length * BITS;
STRING string;
string.message = (char *)malloc(msg_length + bit_length + APP_SIZE / BITS);
strncpy ( string.message, argv, msg_length );
memset ( string.message + msg_length, 0, bit_length );
memmove ( string.message + msg_length + bit_length, (char *)&app_length, sizeof( UINT64 ) );
string.message [ msg_length ] = (char)SINGLE_ONE_BIT;
string.length = msg_length + bit_length + sizeof( UINT64 );
return string;
}
int main ( int argc, char *argv[] )
{
STRING string;
UINT32 w[16];
UINT32 h0, a;
UINT32 h1, b;
UINT32 h2, c;
UINT32 h3, d;
unsigned char r[16];
int i;
int j;
char m[16],md5[512]={0};
char word[512];
gets(word);
string = append_padding_bits (word);
h0 = A;
h1 = B;
h2 = C;
h3 = D;
for ( j = 0; j < string.length; j += BLOCK_SIZE / BITS)
{
memmove ( (char *)w, string.message + j, BLOCK_SIZE / BITS );
a = h0;
b = h1;
c = h2;
d = h3;
// Round 1
FF( a, b, c, d, w[0], 7, 0xd76aa478);
FF( d, a, b, c, w[1], 12, 0xe8c7b756);
FF( c, d, a, b, w[2], 17, 0x242070db);
FF( b, c, d, a, w[3], 22, 0xc1bdceee);
FF( a, b, c, d, w[4], 7, 0xf57c0faf);
FF( d, a, b, c, w[5], 12, 0x4787c62a);
FF( c, d, a, b, w[6], 17, 0xa8304613);
FF( b, c, d, a, w[7], 22, 0xfd469501);
FF( a, b, c, d, w[8], 7, 0x698098d8);
FF( d, a, b, c, w[9], 12, 0x8b44f7af);
FF( c, d, a, b, w[10], 17, 0xffff5bb1);
FF( b, c, d, a, w[11], 22, 0x895cd7be);
FF( a, b, c, d, w[12], 7, 0x6b901122);
FF( d, a, b, c, w[13], 12, 0xfd987193);
FF( c, d, a, b, w[14], 17, 0xa679438e);
FF( b, c, d, a, w[15], 22, 0x49b40821);
// Round 2
GG( a, b, c, d, w[1], 5, 0xf61e2562 );
GG( d, a, b, c, w[6], 9, 0xc040b340 );
GG( c, d, a, b, w[11], 14, 0x265e5a51 );
GG( b, c, d, a, w[0], 20, 0xe9b6c7aa );
GG( a, b, c, d, w[5], 5, 0xd62f105d );
GG( d, a, b, c, w[10], 9, 0x02441453 );
GG( c, d, a, b, w[15], 14, 0xd8a1e681 );
GG( b, c, d, a, w[4], 20, 0xe7d3fbc8 );
GG( a, b, c, d, w[9], 5, 0x21e1cde6 );
GG( d, a, b, c, w[14], 9, 0xc33707d6 );
GG( c, d, a, b, w[3], 14, 0xf4d50d87 );
GG( b, c, d, a, w[8], 20, 0x455a14ed );
GG( a, b, c, d, w[13], 5, 0xa9e3e905 );
GG( d, a, b, c, w[2], 9, 0xfcefa3f8 );
GG( c, d, a, b, w[7], 14, 0x676f02d9 );
GG( b, c, d, a, w[12], 20, 0x8d2a4c8a );
// Round 3
HH( a, b, c, d, w[5], 4, 0xfffa3942 );
HH( d, a, b, c, w[8], 11, 0x8771f681 );
HH( c, d, a, b, w[11], 16, 0x6d9d6122 );
HH( b, c, d, a, w[14], 23, 0xfde5380c );
HH( a, b, c, d, w[1], 4, 0xa4beea44 );
HH( d, a, b, c, w[4], 11, 0x4bdecfa9 );
HH( c, d, a, b, w[7], 16, 0xf6bb4b60 );
HH( b, c, d, a, w[10], 23, 0xbebfbc70 );
HH( a, b, c, d, w[13], 4, 0x289b7ec6 );
HH( d, a, b, c, w[0], 11, 0xeaa127fa );
HH( c, d, a, b, w[3], 16, 0xd4ef3085 );
HH( b, c, d, a, w[6], 23, 0x04881d05 );
HH( a, b, c, d, w[9], 4, 0xd9d4d039 );
HH( d, a, b, c, w[12], 11, 0xe6db99e5 );
HH( c, d, a, b, w[15], 16, 0x1fa27cf8 );
HH( b, c, d, a, w[2], 23, 0xc4ac5665 );
// Round 4
II( a, b, c, d, w[0], 6, 0xf4292244 );
II( d, a, b, c, w[7], 10, 0x432aff97 );
II( c, d, a, b, w[14], 15, 0xab9423a7 );
II( b, c, d, a, w[5], 21, 0xfc93a039 );
II( a, b, c, d, w[12], 6, 0x655b59c3 );
II( d, a, b, c, w[3], 10, 0x8f0ccc92 );
II( c, d, a, b, w[10], 15, 0xffeff47d );
II( b, c, d, a, w[1], 21, 0x85845dd1 );
II( a, b, c, d, w[8], 6, 0x6fa87e4f );
II( d, a, b, c, w[15], 10, 0xfe2ce6e0 );
II( c, d, a, b, w[6], 15, 0xa3014314 );
II( b, c, d, a, w[13], 21, 0x4e0811a1 );
II( a, b, c, d, w[4], 6, 0xf7537e82 );
II( d, a, b, c, w[11], 10, 0xbd3af235 );
II( c, d, a, b, w[2], 15, 0x2ad7d2bb );
II( b, c, d, a, w[9], 21, 0xeb86d391 );
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
memmove ( r + 0, (char *)&h0, sizeof(h0) );
memmove ( r + 4, (char *)&h1, sizeof(h1) );
memmove ( r + 8, (char *)&h2, sizeof(h2) );
memmove ( r + 12, (char *)&h3, sizeof(h3) );
for ( i = 0; i < 16; i++ )
{
sprintf ( m,"%02x", r[i] ); //:%02x 是指输出两位16 进制数.如果不足两位则在前面补0
strcat(md5,m);
//puts(m);
}
puts(md5);
putchar ( '\n' );
// printf ( "%08x%08x%08x%08x\n", h0, h1, h2, h3 );
return EXIT_SUCCESS;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。