1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| #include <iostream> #include <string> #include <stdint.h> #include <limits.h>
using namespace std;
const uint32_t T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
const unsigned int SHIFT[4][4]{ {7, 12, 17, 22}, {5, 9, 14, 20}, {4, 11, 16, 23}, {6, 10, 15, 21}};
const uint8_t PADDING[] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void padmes(string message, uint8_t *mes1) { uint64_t mesL=message.length(); uint64_t bitmesL=mesL*CHAR_BIT; int block =(bitmesL+64)/512+1; memcpy(mes1, message.c_str(), mesL); for( int i =mesL;i<(block*64-8);i++){ mes1[i]=PADDING[i-mesL]; } memcpy(mes1+(block*64-8), &bitmesL, 8);
}
uint32_t Left_Rotate(uint32_t x, unsigned int n) { n&=31; return (x << n) | (x >> (32-n)); } uint32_t FF(int i ,uint32_t b, uint32_t c, uint32_t d) { switch (i) { case 0: return (b & c) | (~b & d); case 1: return (b & d) | (c & (~d)); case 2: return b ^ c ^ d; case 3: return c ^ (b | (~d)); } return 0; } unsigned int Subs(int round_i,int i){ switch ( round_i){ case 0: return i; case 1: return (5*i+1)%16; case 2: return (3*i+5)%16; case 3: return (7*i)%16; } return 0; } void Round_F(int Round_i,uint32_t buffer[4],const uint32_t X[16]) { for (int i =0;i<16;i++){ buffer[0]+=FF(Round_i,buffer[1],buffer[2],buffer[3]); buffer[0]+=X[Subs(Round_i,i)]; buffer[0]+=T[i+Round_i*16]; buffer[0]=Left_Rotate(buffer[0],SHIFT[Round_i][i%4]); buffer[0]+=buffer[1]; uint32_t temp=buffer[3]; buffer[3]=buffer[2]; buffer[2]=buffer[1]; buffer[1]=buffer[0]; buffer[0]=temp; } return ; } void oneMD5(uint32_t chain_vetor[4],const uint32_t X[16]) { uint32_t buffer[4]; for (int i =0;i<4;i++){ buffer[i]=chain_vetor[i]; } for (int i =0;i<4;i++){ Round_F(i,buffer,X); } for (int i =0;i<4;i++){ chain_vetor[i]+=buffer[i]; } } __uint128_t MD5(string message){ uint64_t mesL=message.length(); uint64_t bitmesL=mesL*CHAR_BIT; uint64_t block =(bitmesL+64)/512+1; uint8_t mes1[block*64]; uint32_t chain_vetor[4]={0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476}; padmes(message, mes1); uint32_t *X=new uint32_t[16]; for (int i =0;i<block;i++){ memcpy(X,mes1+64*i,64); oneMD5(chain_vetor,X); } __uint128_t md5 = 0; for (int i = 0; i < 4; i++) md5 += (__uint128_t)chain_vetor[i] << (i * 32);
delete[] X; return md5; } void MD5_Print(__uint128_t in) { unsigned char *ptr = (unsigned char *)∈ for (int i = 0; i < 16; i++) printf("%02x", ptr[i]); }
int main(){ cout << "----------------- MD5 -----------------\n"; cout << "-----------------------\n"; string str; while (1) { cout << "text: "; getline(cin, str); __uint128_t md5 = MD5(str);
cout << "result: "; MD5_Print(md5); if(str == "Please_let_me_go~") break; cout << "\n-----------------------\n"; }
return 0; }
|