MD5 實作
剩餘的64 bits 給原始的字串長度(bit length)
"aakljhsdfglihjaewlkasldfkj aldkjgaid a iuehn cxzhjbqwe lknKJDNF UHEWK RJNAKS KHWEIURHKAJSNDBVAJksjdhfa adfkjh"
01100001 97 01100001 97 01101011 107 01101100 108 01101010 106 01101000 104
01110011 115 01100100 100 01100110 102 01100111 103 01101100 108 01101001 105
01101000 104 01101010 106 01100001 97 01100101 101 01110111 119 01101100 108
01101011 107 01100001 97 01110011 115 01101100 108 01100100 100 01100110 102
01101011 107 01101010 106 00100000 32 01100001 97 01101100 108 01100100 100
01101011 107 01101010 106 01100111 103 01100001 97 01101001 105 01100100 100
00100000 32 01100001 97 00100000 32 01101001 105 01110101 117 01100101 101
01101000 104 01101110 110 00100000 32 01100011 99 01111000 120 01111010 122
01101000 104 01101010 106 01100010 98 01110001 113 01110111 119 01100101 101
00100000 32 01101100 108 01101011 107 01101110 110 01001011 75 01001010 74
01000100 68 01001110 78 01000110 70 00100000 32 00100000 32 01010101 85
01001000 72 01000101 69 01010111 87 01001011 75 00100000 32 01010010 82
01001010 74 01001110 78 01000001 65 01001011 75 01010011 83 00100000 32
01001011 75 01001000 72 01010111 87 01000101 69 01001001 73 01010101 85
01010010 82 01001000 72 01001011 75 01000001 65 01001010 74 01010011 83
01001110 78 01000100 68 01000010 66 01010110 86 01000001 65 01001010 74
01101011 107 01110011 115 01101010 106 01100100 100 01101000 104 01100110 102
01100001 97 00100000 32 01100001 97 01100100 100 01100110 102 01101011 107
01101010 106 01101000 104 10000000 128 00000000 0 00000000 0 00000000 0
00000000 0 00000000 0 00000000 0 00000000 0 00000000 0 00000000 0
01110000 112 00000011 3 00000000 0 00000000 0 00000000 0 00000000 0
00000000 0 00000000 0
範例輸入 :
a
abc
message digest
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
abcdefg
-
範例輸出 :
D41D8CD98F00B204E9800998ECF8427E
0CC175B9C0F1B6A831C399E269772661
DAA1A373AFB44D2540D6452013C23C82
F96B697D7CB7938D525A2F31AAF161D0
C3FCD3D76192E4007DFB496CCA67E13B
F29939A25EFABAEF3B87E2CBFE641315
3718A5F5B3212D3D1C782436FADB1C3A
E7C4509687A708D1FF1F409212D903FB
以下程式碼, 參考百度的寫法, 多了一些自己的做法, 不過還是靜態的
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
typedef unsigned long UINT32;
typedef unsigned long long UINT64;
UINT32 F(UINT32 x, UINT32 y, UINT32 z) {
return (x & y) | (~x & z);
}
UINT32 G(UINT32 x, UINT32 y, UINT32 z) {
return (x & z) | (y & ~z);
}
UINT32 H(UINT32 x, UINT32 y, UINT32 z) {
return x ^ y ^ z;
}
UINT32 I(UINT32 x, UINT32 y, UINT32 z) {
return y ^ (x | ~z);
}
UINT32 rotate_left(UINT32 x, UINT32 n) {
return (x << n) | (x >> (32-n));
}
void MD5(char in[]) {
UINT32 S[4][4] = {{7, 12, 17, 22}, {5, 9, 14, 20}, {4, 11, 16, 23}, {6, 10, 15, 21}};
UINT32 X[16], T[65], chain[4] ={0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
UINT32 Xinit[4][2] = {{0, 1}, {1, 5}, {5, 3}, {0, 7}};
int i, j, roundIdx, xIdx, sIdx;
UINT32 ( *Function[4])(UINT32, UINT32, UINT32) = {F, G, H, I};
for(i = 1; i <= 64; i++) T[i] = (UINT32)floor((1ULL << 32)*fabs(sin(i)));
UINT32 length = strlen(in)+1, bit_length = 8*length, tlength = (length-1)*8;
UINT32 Copy[length+513], supply, state[4];
for(i = 0; i < length; i++) Copy[i] = in[i] < 0 ? (128-abs(in[i]))+(1<<7) : in[i];
Copy[length-1] = 1 << 7;
supply = bit_length % 512;
supply = (supply > 448) ? (512-supply+448) : (448-supply);
for(i = supply/8; i >= 0; i--, length++) Copy[length] = 0;
for(i = length-1; tlength; i++)
Copy[i] = tlength % 256, tlength /= 256;
bit_length = (length-1)*8+64, length = bit_length/8;
for(i = 0; i < length; i += 64) {
state[0] = chain[0], state[1] = chain[1];
state[2] = chain[2], state[3] = chain[3];
for(j = 0; j < 16; j++)
X[j] = (Copy[i+j*4+3]<<24) | (Copy[i+j*4+2]<<16) | (Copy[i+j*4+1]<<8) | Copy[i+j*4];
for(roundIdx = 0; roundIdx < 4; roundIdx++) {
xIdx = Xinit[roundIdx][0], sIdx = 0;
for(j = 0; j < 16; j++) {
state[sIdx] = state[(sIdx+1)%4] + rotate_left(
state[sIdx] + ( *Function[roundIdx])(state[(sIdx+1)%4], state[(sIdx+2)%4], state[(sIdx+3)%4])
+ X[xIdx] + T[roundIdx*16+j+1], S[roundIdx][j%4]
);
sIdx = (sIdx + 3) % 4;
xIdx = (xIdx + Xinit[roundIdx][1]) & 0xF;
}
}
chain[0] += state[0], chain[1] += state[1];
chain[2] += state[2], chain[3] += state[3];
}
char r[33];
for(i = 0; i < 4; i++)
for(j = 0; j < 8; j += 2)
sprintf(r+i*8+j, "%02X", chain[i] & 0xff), chain[i] >>= 8;
r[32] = '\0';
puts(r);
}
main() {
char S[20000];
while(gets(S))
MD5(S);
return 0;
}