내용으로 건너뛰기
사용자 도구
로그인
사이트 도구
도구
문서 보기
이전 판
백링크
최근 바뀜
미디어 관리
사이트맵
로그인
최근 바뀜
미디어 관리
사이트맵
기술자료
작업공간
개인공간
사이트맵
추적:
kb:md5hashing
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== MD5 Hashing ====== MD5는 해쉬 알고리즘의 일종이다. 즉 문자열이나 파일 같은 것을 읽어들여서 이를 일정한 값으로 요악하는 알고리즘이다. 암호화와 관련해서 원문 확인용으로 쓰일 때가 있다. Win32에서도 사용가능한 함수가 있기는 하지만, [[Base64Encoding]]과 관련해서 인터넷을 뒤지다가 있길래 같이 만들어버렸다. ====== C++ Implementation ====== <file cpp MD5.h> ////////////////////////////////////////////////////////////////////////////// // Filename : MD5.h // Written By : excel96 // Created : 2003.3.6 // Description : ////////////////////////////////////////////////////////////////////////////// #ifndef __MD5_H__ #define __MD5_H__ #ifndef __MTYPES_H__ #include "MTypes.h" #endif #ifndef _INC_STDIO #include <stdio.h> #endif #ifndef _FSTREAM_ #include <fstream> #endif #ifndef _IOSTREAM_ #include <iostream> #endif ////////////////////////////////////////////////////////////////////////////// // Classname : MD5 // Description : ////////////////////////////////////////////////////////////////////////////// // TEST SUITE // MD5 ("") = d41d8cd98f00b204e9800998ecf8427e // MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 // MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 // MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 // MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b // MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = // d174ab98d277d9f5a5611c2c9f419d9f // MD5 ("123456789012345678901234567890123456789012345678901234567890123456 // 78901234567890") = 57edf4a22be3c955ac49da2e2107b67a ////////////////////////////////////////////////////////////////////////////// class MD5 { private: static BYTE PADDING[64]; DWORD m_pState[4]; DWORD m_pCount[2]; // number of* bits*, mod 2^64 BYTE m_pBuffer[64]; // input buffer BYTE m_pDigest[16]; BYTE m_bFinalized; public: MD5(); // simple initializer MD5(BYTE* pString); // digest string, finalize MD5(istream& stream); // digest stream, finalize MD5(FILE* file); // digest file, close, finalize MD5(ifstream& stream); // digest stream, close, finalize public: void update(BYTE* input, DWORD input_length); void update(istream& stream); void update(FILE* file); void update(ifstream& stream); void finalize(); public: // digest as a 16-byte binary array // don't forget to delete returned array BYTE* digest2binary(); // digest as a 33-byte ascii-hex string string digest2hexstring(); // test function static bool testMe(); private: // called by all constructors void init(); // does the real update work. Note that length is implied to be 64. void transform(BYTE* buffer); static void encode(BYTE* dest, DWORD* src, DWORD length); static void decode(DWORD* dest, BYTE* src, DWORD length); static void memcpy(BYTE* dest, BYTE* src, DWORD length); static void memset(BYTE* start, BYTE val, DWORD length); static inline DWORD rotate_left(DWORD x, DWORD n); static inline DWORD F(DWORD x, DWORD y, DWORD z); static inline DWORD G(DWORD x, DWORD y, DWORD z); static inline DWORD H(DWORD x, DWORD y, DWORD z); static inline DWORD I(DWORD x, DWORD y, DWORD z); static inline void FF(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac); static inline void GG(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac); static inline void HH(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac); static inline void II(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac); }; #endif //__MD5_H__ </file> <file cpp MD5.cpp> ////////////////////////////////////////////////////////////////////////////// // Filename : MD5.cpp // Written By : excel96 // Created : 2003.3.6 // Description : ////////////////////////////////////////////////////////////////////////////// #include "MD5.h" #include <iostream> // Constants for MD5Transform routine. // Although we could use C++ style constants, defines are actually better, // since they let us easily evade scope clashes. #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 BYTE MD5::PADDING[64] = { 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 }; ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::MD5 // Return type : // Description : // MD5 simple initialization method ////////////////////////////////////////////////////////////////////////////// MD5::MD5() { init(); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::MD5 // Return type : // Argument : BYTE* pString // Description : ////////////////////////////////////////////////////////////////////////////// MD5::MD5(BYTE* pString) { init(); // must be called be all constructors update(pString, strlen((const char*)pString)); finalize(); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::MD5 // Return type : // Argument : FILE *file // Description : ////////////////////////////////////////////////////////////////////////////// MD5::MD5(FILE *file) { init(); // must be called be all constructors update(file); finalize(); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::MD5 // Return type : // Argument : istream& stream // Description : ////////////////////////////////////////////////////////////////////////////// MD5::MD5(istream& stream) { init(); // must called by all constructors update(stream); finalize(); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::MD5 // Return type : // Argument : ifstream& stream // Description : ////////////////////////////////////////////////////////////////////////////// MD5::MD5(ifstream& stream) { init(); // must called by all constructors update(stream); finalize(); } ////////////////////////////////////////////////////////////////////////////// // Function name : // Return type : void MD5::update // Argument : BYTE *input // Argument : DWORD input_length // Description : // MD5 block update operation. Continues an MD5 message-digest // operation, processing another message block, and updating the // context. ////////////////////////////////////////////////////////////////////////////// void MD5::update(BYTE* input, DWORD input_length) { DWORD input_index, buffer_index; DWORD buffer_space; // how much space is left in buffer if (m_bFinalized) { // so we can't update! cerr << "MD5::update: Can't update a finalized digest!" << endl; return; } // Compute number of bytes mod 64 buffer_index = (DWORD)((m_pCount[0] >> 3) & 0x3F); // Update number of bits if ((m_pCount[0] += ((DWORD) input_length << 3))<((DWORD) input_length << 3)) m_pCount[1]++; m_pCount[1] += ((DWORD)input_length >> 29); buffer_space = 64 - buffer_index; // how much space is left in buffer // Transform as many times as possible. if (input_length >= buffer_space) { // ie. we have enough to fill the buffer // fill the rest of the buffer and transform MD5::memcpy(m_pBuffer + buffer_index, input, buffer_space); transform(m_pBuffer); // now, transform each 64-byte piece of the input, bypassing the buffer for (input_index = buffer_space; input_index + 63 < input_length; input_index += 64) transform(input+input_index); buffer_index = 0; // so we can buffer remaining } else { input_index=0; // so we can buffer the whole input } // and here we do the buffering: MD5::memcpy(m_pBuffer+buffer_index, input+input_index, input_length-input_index); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::update // Return type : void // Argument : FILE *file // Description : // MD5 update for files. // Like above, except that it works on files(and uses above as a primitive.) ////////////////////////////////////////////////////////////////////////////// void MD5::update(FILE *file) { BYTE buffer[1024]; int len; while (len = fread(buffer, 1, 1024, file)) update(buffer, len); fclose(file); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::update // Return type : void // Argument : istream& stream // Description : // MD5 update for istreams. // Like update for files; see above. ////////////////////////////////////////////////////////////////////////////// void MD5::update(istream& stream) { BYTE buffer[1024]; int len; while (stream.good()) { // note that return value of read is unusable. stream.read((char*)&buffer[0], 1024); len = stream.gcount(); update(buffer, len); } } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::update // Return type : void // Argument : ifstream& stream // Description : // MD5 update for ifstreams. // Like update for files; see above. ////////////////////////////////////////////////////////////////////////////// void MD5::update(ifstream& stream) { BYTE buffer[1024]; int len; while (stream.good()) { // note that return value of read is unusable. stream.read((char*)&buffer[0], 1024); len = stream.gcount(); update(buffer, len); } } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::finalize // Return type : void // Description : // MD5 finalization. Ends an MD5 message-digest operation, // writing the the message digest and zeroizing the context. ////////////////////////////////////////////////////////////////////////////// void MD5::finalize() { BYTE bits[8]; DWORD index, padLen; if (m_bFinalized) { cerr << "MD5::finalize: Already finalized this digest!" << endl; return; } // Save number of bits encode(bits, m_pCount, 8); // Pad out to 56 mod 64. index = (DWORD)((m_pCount[0] >> 3) & 0x3f); padLen = (index < 56) ?(56 - index) :(120 - index); update(MD5::PADDING, padLen); // Append length(before padding) update(bits, 8); // Store state in digest encode(m_pDigest, m_pState, 16); // Zeroize sensitive information MD5::memset(m_pBuffer, 0, sizeof(*m_pBuffer)); m_bFinalized = true; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::digest2binary // Return type : BYTE* // Description : ////////////////////////////////////////////////////////////////////////////// BYTE* MD5::digest2binary() { BYTE *s = new BYTE[16]; if (!m_bFinalized) { cerr << "MD5::digest2binary: " << "Can't get digest if you haven't finalized the digest!" << endl; return ((BYTE*)""); } MD5::memcpy(s, m_pDigest, 16); return s; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::digest2hexstring // Return type : string // Description : ////////////////////////////////////////////////////////////////////////////// string MD5::digest2hexstring() { if (!m_bFinalized) { cerr << "MD5::digest2hexstring: " << "Can't get digest if you haven't finalized the digest!" << endl; return ""; } char s[34] = {0, }; for (int i=0; i < 16; i++) { sprintf(s + i*2, "%02x", m_pDigest[i]); } s[32] = '\0'; return string(s); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::testMe // Return type : bool // Description : // test function ////////////////////////////////////////////////////////////////////////////// bool MD5::testMe() { char* input[7] = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; string expected[7] = { "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a" }; MD5 test1((BYTE*)input[0]); MD5 test2((BYTE*)input[1]); MD5 test3((BYTE*)input[2]); MD5 test4((BYTE*)input[3]); MD5 test5((BYTE*)input[4]); MD5 test6((BYTE*)input[5]); MD5 test7((BYTE*)input[6]); if (test1.digest2hexstring() != expected[0]) return false; if (test2.digest2hexstring() != expected[1]) return false; if (test3.digest2hexstring() != expected[2]) return false; if (test4.digest2hexstring() != expected[3]) return false; if (test5.digest2hexstring() != expected[4]) return false; if (test6.digest2hexstring() != expected[5]) return false; if (test7.digest2hexstring() != expected[6]) return false; return true; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::init // Return type : void // Description : ////////////////////////////////////////////////////////////////////////////// void MD5::init() { m_bFinalized = false; // we just started! // Nothing counted, so count=0 m_pCount[0] = 0; m_pCount[1] = 0; // Load magic initialization constants. m_pState[0] = 0x67452301; m_pState[1] = 0xefcdab89; m_pState[2] = 0x98badcfe; m_pState[3] = 0x10325476; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::transform // Return type : void // Argument : BYTE block[64] // Description : // MD5 basic transformation. Transforms state based on block. ////////////////////////////////////////////////////////////////////////////// void MD5::transform(BYTE block[64]) { DWORD a = m_pState[0]; DWORD b = m_pState[1]; DWORD c = m_pState[2]; DWORD d = m_pState[3]; DWORD x[16]; decode(x, block, 64); // not just a user error, since the method is private Assert(!m_bFinalized); /* Round 1 */ FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ m_pState[0] += a; m_pState[1] += b; m_pState[2] += c; m_pState[3] += d; // Zeroize sensitive information. MD5::memset((BYTE *) x, 0, sizeof(x)); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::encode // Return type : void // Argument : BYTE *output // Argument : DWORD *input // Argument : DWORD len // Description : // Encodes input(UINT4) into output(BYTE). // Assumes len is a multiple of 4. ////////////////////////////////////////////////////////////////////////////// void MD5::encode(BYTE *output, DWORD *input, DWORD len) { DWORD i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (BYTE) (input[i] & 0xff); output[j+1] = (BYTE)((input[i] >> 8) & 0xff); output[j+2] = (BYTE)((input[i] >> 16) & 0xff); output[j+3] = (BYTE)((input[i] >> 24) & 0xff); } } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::decode // Return type : void // Argument : DWORD* output // Argument : BYTE* input // Argument : DWORD len // Description : // Decodes input(BYTE) into output(UINT4). // Assumes len is a multiple of 4. ////////////////////////////////////////////////////////////////////////////// void MD5::decode(DWORD* output, BYTE* input, DWORD len) { DWORD i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[i] = ((DWORD)input[j]) | (((DWORD)input[j+1]) << 8) | (((DWORD)input[j+2]) << 16) |(((DWORD)input[j+3]) << 24); } } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::memcpy // Return type : void // Argument : BYTE* output // Argument : BYTE* input // Argument : DWORD len // Description : // Note: Replace "for loop" with standard memcpy if possible. ////////////////////////////////////////////////////////////////////////////// void MD5::memcpy(BYTE* output, BYTE* input, DWORD len) { for (DWORD i = 0; i < len; i++) output[i] = input[i]; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::memset // Return type : void // Argument : BYTE* output // Argument : BYTE value // Argument : DWORD len // Description : // Note: Replace "for loop" with standard memset if possible. ////////////////////////////////////////////////////////////////////////////// void MD5::memset(BYTE* output, BYTE value, DWORD len) { for (DWORD i = 0; i < len; i++) output[i] = value; } ////////////////////////////////////////////////////////////////////////////// // Function name : int MD5::rotate_left // Return type : unsigned // Argument : DWORD x // Argument : DWORD n // Description : // ROTATE_LEFT rotates x left n bits. ////////////////////////////////////////////////////////////////////////////// inline DWORD MD5::rotate_left(DWORD x, DWORD n) { return(x << n) |(x >>(32-n)) ; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::F // Return type : DWORD // Argument : DWORD x // Argument : DWORD y // Argument : DWORD z // Description : // F, G, H and I are basic MD5 functions. ////////////////////////////////////////////////////////////////////////////// inline DWORD MD5::F(DWORD x, DWORD y, DWORD z) { return(x & y) |(~x & z); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::G // Return type : DWORD // Argument : DWORD x // Argument : DWORD y // Argument : DWORD z // Description : // F, G, H and I are basic MD5 functions. ////////////////////////////////////////////////////////////////////////////// inline DWORD MD5::G(DWORD x, DWORD y, DWORD z) { return(x & z) |(y & ~z); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::H // Return type : DWORD // Argument : DWORD x // Argument : DWORD y // Argument : DWORD z // Description : // F, G, H and I are basic MD5 functions. ////////////////////////////////////////////////////////////////////////////// inline DWORD MD5::H(DWORD x, DWORD y, DWORD z) { return x ^ y ^ z; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::I // Return type : DWORD // Argument : DWORD x // Argument : DWORD y // Argument : DWORD z // Description : // F, G, H and I are basic MD5 functions. ////////////////////////////////////////////////////////////////////////////// inline DWORD MD5::I(DWORD x, DWORD y, DWORD z) { return y ^(x | ~z); } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::FF // Return type : void // Argument : DWORD& a // Argument : DWORD b // Argument : DWORD c // Argument : DWORD d // Argument : DWORD x // Argument : DWORD s // Argument : DWORD ac // Description : // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. ////////////////////////////////////////////////////////////////////////////// inline void MD5::FF(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac) { a += F(b, c, d) + x + ac; a = rotate_left(a, s) +b; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::GG // Return type : void // Argument : DWORD& a // Argument : DWORD b // Argument : DWORD c // Argument : DWORD d // Argument : DWORD x // Argument : DWORD s // Argument : DWORD ac // Description : // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. ////////////////////////////////////////////////////////////////////////////// inline void MD5::GG(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac) { a += G(b, c, d) + x + ac; a = rotate_left(a, s) +b; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::HH // Return type : void // Argument : DWORD& a // Argument : DWORD b // Argument : DWORD c // Argument : DWORD d // Argument : DWORD x // Argument : DWORD s // Argument : DWORD ac // Description : // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. ////////////////////////////////////////////////////////////////////////////// inline void MD5::HH(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac) { a += H(b, c, d) + x + ac; a = rotate_left(a, s) +b; } ////////////////////////////////////////////////////////////////////////////// // Function name : MD5::II // Return type : void // Argument : DWORD& a // Argument : DWORD b // Argument : DWORD c // Argument : DWORD d // Argument : DWORD x // Argument : DWORD s // Argument : DWORD ac // Description : // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. ////////////////////////////////////////////////////////////////////////////// inline void MD5::II(DWORD& a, DWORD b, DWORD c, DWORD d, DWORD x, DWORD s, DWORD ac) { a += I(b, c, d) + x + ac; a = rotate_left(a, s) +b; } </file> ---- * see also [[Cryptography]]
kb/md5hashing.txt
· 마지막으로 수정됨: 2014/11/10 19:49 (바깥 편집)
문서 도구
문서 보기
이전 판
백링크
맨 위로