水無瀬の部屋 > Programming > sample > tools > misc > md5.cpp |
---|
1: //*********************************************************
2: // プロジェクト: TOOLS::MD5 - Message-Digest Algorithm
3: // ファイル名: md5.cpp
4: //*********************************************************
5: #include <misc/md5.h> //
6: #include <header/tooldbg.h> // ASSERT(),
7: #include <header/toolbase.h> //
8: #include <header/snprintf.h> // snprintf(), vsnprintf(),
9: #include <limits.h> // CHAR_BIT,
10:
11:
12: //---------------------------------------------------------
13: // テスト関数 の 宣言
14: //---------------------------------------------------------
15: DECLARE_TESTPROC( test_md5 );
16:
17:
18: //---------------------------------------------------------
19: // 定数型マクロ の 定義
20: //---------------------------------------------------------
21: #define DBG_ALLOCNAME "MD5_CreateAlgorithm"
22:
23: //
24: #define S11 7
25: #define S12 12
26: #define S13 17
27: #define S14 22
28: #define S21 5
29: #define S22 9
30: #define S23 14
31: #define S24 20
32: #define S31 4
33: #define S32 11
34: #define S33 16
35: #define S34 23
36: #define S41 6
37: #define S42 10
38: #define S43 15
39: #define S44 21
40:
41:
42: //---------------------------------------------------------
43: // マクロ関数 の 定義
44: //---------------------------------------------------------
45: // F, G, H, I are basic MD5 functions.
46: static inline DWORD F( DWORD x, DWORD y, DWORD z ){ return (x & y) | (~x & z); }
47: static inline DWORD G( DWORD x, DWORD y, DWORD z ){ return (x & z) | (y & ~z); }
48: static inline DWORD H( DWORD x, DWORD y, DWORD z ){ return x ^ y ^ z; }
49: static inline DWORD I( DWORD x, DWORD y, DWORD z ){ return y ^ (x | ~z); }
50:
51: // ROTATE_LEFT rotates x left n bits.
52: static inline DWORD ROTATE_LEFT( DWORD x, DWORD n ){ return (x << n) | (x >> ((CHAR_BIT * sizeof(DWORD)) - n)); }
53:
54: // MD5_MAKEDWORD
55: static inline DWORD MD5_MAKEDWORD( BYTE b1, BYTE b2, BYTE b3, BYTE b4 ){ return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); }
56:
57:
58: //---------------------------------------------------------
59: // 構造体 の 宣言
60: //---------------------------------------------------------
61: typedef struct MD5_CTX_tag
62: {
63: DWORD state[ 4 ];
64: BYTE buffer[ 64 ];
65:
66: // 総バイト数
67: // [0] xxxxxxxxxxxxxxxxxxxxxxxxxxxxx000 , 総バイト数の下位 29 bits
68: // [1] 00000000000000000000000000000xxx , 総バイト数の上位 3 bits
69: DWORD count[ 2 ];
70: DWORD _count;
71: } MD5_CTX;
72:
73:
74: //---------------------------------------------------------
75: // ファイルスコープ関数 の 宣言
76: //---------------------------------------------------------
77: static void MD5_Transform( DWORD state[4], const BYTE block[64], int count );
78: static bool MD5_Encode( BYTE *dst, int bufsize, const DWORD *src, int count );
79: static void MD5_Decode( DWORD *dst, int count, const BYTE *src, int length );
80: static bool MD5_IsValidContext( const MD5_CTX *context );
81:
82:
83: //---------------------------------------------------------
84: // ファイルスコープ変数 の 定義
85: //---------------------------------------------------------
86: static const BYTE PADDING[ 64 ] =
87: {
88: 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
96: };
97:
98:
99: //*********************************************************
100: // MD5_CreateAlgorithm
101: //*********************************************************
102: MD5_CTX *
103: MD5_CreateAlgorithm
104: (
105: void
106: )
107: {
108: CALLONCE_TESTPROC( test_md5 ); // [テスト]
109:
110: MD5_CTX *context = (MD5_CTX *)malloc( sizeof( *context ) );
111: if ( !context )
112: return null;
113:
114: MD5_InitData( context );
115: ASSERT( MD5_IsValidContext( context ) );
116:
117: DBG_LOCK_ALLOCED_MEMORY( context, DBG_ALLOCNAME ); // [DBG]
118: return context;
119: }//MD5_CreateAlgorithm
120:
121: //*********************************************************
122: // MD5_DestroyAlgorithm
123: //*********************************************************
124: bool
125: MD5_DestroyAlgorithm
126: (
127: MD5_CTX *context
128: )
129: {
130: // パラメタの仮定
131: ASSERT( MD5_IsValidContext( context ) );
132:
133: DBG_UNLOCK_ALLOCED_MEMORY( context, DBG_ALLOCNAME ); // [DBG]
134: free( context );
135:
136: return true;
137: }//MD5_DestroyAlgorithm
138:
139: //*********************************************************
140: // MD5_InitData
141: //*********************************************************
142: bool
143: MD5_InitData
144: (
145: MD5_CTX *context
146: )
147: {
148: // パラメタの仮定
149: ASSERT( IsValidPtr( context, sizeof( *context ) ) );
150:
151: context->_count = 0;
152: context->count[ 0 ] = 0;
153: context->count[ 1 ] = 0;
154:
155: context->state[ 0 ] = 0x67452301;
156: context->state[ 1 ] = 0xefcdab89;
157: context->state[ 2 ] = 0x98badcfe;
158: context->state[ 3 ] = 0x10325476;
159:
160: ASSERT( MD5_IsValidContext( context ) );
161: return true;
162: }//MD5_InitData
163:
164: //*********************************************************
165: // MD5_AddData
166: //*********************************************************
167: bool
168: MD5_AddData
169: (
170: MD5_CTX *context,
171: const void *data,
172: int length
173: )
174: {
175: // パラメタの仮定
176: ASSERT( MD5_IsValidContext( context ) );
177: ASSERT( 0 < length );
178: ASSERT( IsValidReadPtr( data, length ) );
179:
180: //
181: const BYTE *p = (BYTE *)data;
182: const UINT index = static_cast<UINT>( 0x3F & (context->count[ 0 ] >> 3) );
183: ASSERT( index == (0x3F & context->_count) );
184:
185: //
186: ASSERT( index <= numof( context->buffer ) );
187: const UINT partLen = numof( context->buffer ) - index;
188:
189: //
190: if ( (DWORD)length < partLen )
191: {
192: memcpy( &context->buffer[ index ], &p[ 0 ], length );
193: }
194: else
195: {
196: memcpy( &context->buffer[ index ], p, partLen );
197: MD5_Transform( context->state, context->buffer, numof( context->buffer ) );
198:
199: UINT i;
200: for( i = partLen; i + 63 < (DWORD)length; i += 64 )
201: {
202: MD5_Transform( context->state, &p[ i ], 64 );
203: }
204:
205: // 残りを保存
206: memcpy( &context->buffer[ 0 ], &p[ i ], length - i );
207: }
208:
209: // count を進める
210: context->_count += length;
211: {
212: context->count[ 0 ] += ((DWORD)length << 3);
213: ASSERT( ((DWORD)length << 3) <= context->count[ 0 ] );
214: if ( context->count[ 0 ] < ((DWORD)length << 3) )
215: {
216: UNREACHCODE( "MD5_AddData" );
217: context->count[ 1 ]++;
218: }
219: context->count[ 1 ] += ((DWORD)length >> 29);
220: }
221:
222: return true;
223: }//MD5_AddData
224:
225: //*********************************************************
226: // MD5_GetHash
227: //*********************************************************
228: bool
229: MD5_GetHash
230: (
231: const MD5_CTX *context,
232: void *digest,
233: int bufsize
234: )
235: {
236: // パラメタの仮定
237: ASSERT( MD5_IsValidContext( context ) );
238: ASSERT( 0 < bufsize );
239: ASSERT( IsValidPtr( digest, bufsize ) );
240: DESTROY_BUFFER( digest, bufsize );
241:
242: //
243: BYTE bits[ 8 ];
244: MD5_Encode( bits, sizeof( bits ), context->count, numof( context->count ) );
245: const UINT index = static_cast<UINT>( 0x3F & (context->count[ 0 ] >> 3) );
246: ASSERT( index == (0x3F & context->_count) );
247:
248: const UINT padLen = (index < 56) ? (56 - index) : (120 - index);
249: ASSERT( ( 64 == (8 + index + padLen))
250: || (128 == (8 + index + padLen)) );
251:
252: MD5_CTX tmp_context;
253: memcpy( &tmp_context, context, sizeof( *context ) );
254: context = null;
255:
256: MD5_AddData( &tmp_context, PADDING, padLen );
257: MD5_AddData( &tmp_context, bits, numof( bits ) );
258: ASSERT( 0 == (0x3F & tmp_context._count) );
259: MD5_Encode( (BYTE *)digest, bufsize, tmp_context.state, numof( tmp_context.state ) );
260:
261: return true;
262: }//MD5_GetHash
263:
264: //*********************************************************
265: // MD5_GetHashText
266: //*********************************************************
267: bool
268: MD5_GetHashText
269: (
270: const MD5_CTX *context,
271: char *buffer,
272: int bufsize
273: )
274: {
275: // パラメタの仮定
276: ASSERT( MD5_IsValidContext( context ) );
277: ASSERT( 0 < bufsize );
278: ASSERT( IsValidStringBufferPtr( buffer, bufsize ) );
279: DESTROY_TEXT_BUFFER( buffer, bufsize );
280:
281: //
282: BYTE md5[ MD5_HASHSIZE ];
283: VERIFY( MD5_GetHash( context, md5, sizeof( md5 ) ) );
284:
285: //
286: char text[ 1+MD5_HASHTEXTSIZE ];
287: {
288: char *p = text;
289: {for( int i = 0; i < numof( md5 ); ++i )
290: {
291: snprintf( p, numof(text) - (p - text), "%02x", md5[ i ] );
292: p = strtail( p );
293: }}
294: }
295:
296: //
297: memcpy( buffer, text, min( bufsize, sizeof( text ) ) );
298: buffer[ min( bufsize, numof( text ) ) - 1 ] = '\0';
299:
300: return true;
301: }//MD5_GetHashText
302:
303:
304: //******************************************************************************************************************
305: //
306: //******************************************************************************************************************
307: static inline DWORD R1( 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 ); a += b; return a; }
308: static inline DWORD R2( 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 ); a += b; return a; }
309: static inline DWORD R3( 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 ); a += b; return a; }
310: static inline DWORD R4( 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 ); a += b; return a; }
311:
312:
313: //*********************************************************
314: // MD5_IsValidContext
315: //*********************************************************
316: static
317: bool
318: MD5_IsValidContext
319: (
320: const MD5_CTX *context
321: )
322: {
323: VALID_TEST( context );
324: VALID_TEST( IsValidReadPtr( context, sizeof( *context ) ) );
325: VALID_TEST( 0 == (0x03 & context->count[ 0 ]) );
326: VALID_TEST( 0 == context->count[ 1 ] );
327:
328: return true;
329: }//MD5_IsValidContext
330:
331: //*********************************************************
332: // MD5_Transform
333: //*********************************************************
334: static
335: void
336: MD5_Transform
337: (
338: DWORD *state,
339: const BYTE *block,
340: int count // 64
341: )
342: {
343: // パラメタの仮定
344: ASSERT( 64 == count );
345: /* ASSERT( 64 == bufsize );
346: ASSERT( 16 == bufsize / sizeof(DWORD) ); */
347:
348: DWORD x[ 16 ];
349: DWORD a = state[ 0 ];
350: DWORD b = state[ 1 ];
351: DWORD c = state[ 2 ];
352: DWORD d = state[ 3 ];
353:
354: MD5_Decode( x, numof( x ), block, count );
355:
356: // Round 1
357: {
358: a = R1( a, b, c, d, x[ 0], S11, 0xd76aa478 );
359: d = R1( d, a, b, c, x[ 1], S12, 0xe8c7b756 );
360: c = R1( c, d, a, b, x[ 2], S13, 0x242070db );
361: b = R1( b, c, d, a, x[ 3], S14, 0xc1bdceee );
362:
363: a = R1( a, b, c, d, x[ 4], S11, 0xf57c0faf );
364: d = R1( d, a, b, c, x[ 5], S12, 0x4787c62a );
365: c = R1( c, d, a, b, x[ 6], S13, 0xa8304613 );
366: b = R1( b, c, d, a, x[ 7], S14, 0xfd469501 );
367:
368: a = R1( a, b, c, d, x[ 8], S11, 0x698098d8 );
369: d = R1( d, a, b, c, x[ 9], S12, 0x8b44f7af );
370: c = R1( c, d, a, b, x[10], S13, 0xffff5bb1 );
371: b = R1( b, c, d, a, x[11], S14, 0x895cd7be );
372:
373: a = R1( a, b, c, d, x[12], S11, 0x6b901122 );
374: d = R1( d, a, b, c, x[13], S12, 0xfd987193 );
375: c = R1( c, d, a, b, x[14], S13, 0xa679438e );
376: b = R1( b, c, d, a, x[15], S14, 0x49b40821 );
377: }
378:
379: // Round 2
380: {
381: a = R2( a, b, c, d, x[ 1], S21, 0xf61e2562 );
382: d = R2( d, a, b, c, x[ 6], S22, 0xc040b340 );
383: c = R2( c, d, a, b, x[11], S23, 0x265e5a51 );
384: b = R2( b, c, d, a, x[ 0], S24, 0xe9b6c7aa );
385:
386: a = R2( a, b, c, d, x[ 5], S21, 0xd62f105d );
387: d = R2( d, a, b, c, x[10], S22, 0x02441453 );
388: c = R2( c, d, a, b, x[15], S23, 0xd8a1e681 );
389: b = R2( b, c, d, a, x[ 4], S24, 0xe7d3fbc8 );
390:
391: a = R2( a, b, c, d, x[ 9], S21, 0x21e1cde6 );
392: d = R2( d, a, b, c, x[14], S22, 0xc33707d6 );
393: c = R2( c, d, a, b, x[ 3], S23, 0xf4d50d87 );
394: b = R2( b, c, d, a, x[ 8], S24, 0x455a14ed );
395:
396: a = R2( a, b, c, d, x[13], S21, 0xa9e3e905 );
397: d = R2( d, a, b, c, x[ 2], S22, 0xfcefa3f8 );
398: c = R2( c, d, a, b, x[ 7], S23, 0x676f02d9 );
399: b = R2( b, c, d, a, x[12], S24, 0x8d2a4c8a );
400: }
401:
402: // Round 3
403: {
404: a = R3( a, b, c, d, x[ 5], S31, 0xfffa3942 );
405: d = R3( d, a, b, c, x[ 8], S32, 0x8771f681 );
406: c = R3( c, d, a, b, x[11], S33, 0x6d9d6122 );
407: b = R3( b, c, d, a, x[14], S34, 0xfde5380c );
408:
409: a = R3( a, b, c, d, x[ 1], S31, 0xa4beea44 );
410: d = R3( d, a, b, c, x[ 4], S32, 0x4bdecfa9 );
411: c = R3( c, d, a, b, x[ 7], S33, 0xf6bb4b60 );
412: b = R3( b, c, d, a, x[10], S34, 0xbebfbc70 );
413:
414: a = R3( a, b, c, d, x[13], S31, 0x289b7ec6 );
415: d = R3( d, a, b, c, x[ 0], S32, 0xeaa127fa );
416: c = R3( c, d, a, b, x[ 3], S33, 0xd4ef3085 );
417: b = R3( b, c, d, a, x[ 6], S34, 0x04881d05 );
418:
419: a = R3( a, b, c, d, x[ 9], S31, 0xd9d4d039 );
420: d = R3( d, a, b, c, x[12], S32, 0xe6db99e5 );
421: c = R3( c, d, a, b, x[15], S33, 0x1fa27cf8 );
422: b = R3( b, c, d, a, x[ 2], S34, 0xc4ac5665 );
423: }
424:
425: // Round 4
426: {
427: a = R4( a, b, c, d, x[ 0], S41, 0xf4292244 );
428: d = R4( d, a, b, c, x[ 7], S42, 0x432aff97 );
429: c = R4( c, d, a, b, x[14], S43, 0xab9423a7 );
430: b = R4( b, c, d, a, x[ 5], S44, 0xfc93a039 );
431:
432: a = R4( a, b, c, d, x[12], S41, 0x655b59c3 );
433: d = R4( d, a, b, c, x[ 3], S42, 0x8f0ccc92 );
434: c = R4( c, d, a, b, x[10], S43, 0xffeff47d );
435: b = R4( b, c, d, a, x[ 1], S44, 0x85845dd1 );
436:
437: a = R4( a, b, c, d, x[ 8], S41, 0x6fa87e4f );
438: d = R4( d, a, b, c, x[15], S42, 0xfe2ce6e0 );
439: c = R4( c, d, a, b, x[ 6], S43, 0xa3014314 );
440: b = R4( b, c, d, a, x[13], S44, 0x4e0811a1 );
441:
442: a = R4( a, b, c, d, x[ 4], S41, 0xf7537e82 );
443: d = R4( d, a, b, c, x[11], S42, 0xbd3af235 );
444: c = R4( c, d, a, b, x[ 2], S43, 0x2ad7d2bb );
445: b = R4( b, c, d, a, x[ 9], S44, 0xeb86d391 );
446: }
447:
448: state[ 0 ] += a;
449: state[ 1 ] += b;
450: state[ 2 ] += c;
451: state[ 3 ] += d;
452: }//MD5_Transform
453:
454: //*********************************************************
455: // MD5_Encode
456: // DWORD[ 2 or 4 ] を BYTE[ 8 or 16 ] へ変換
457: //*********************************************************
458: static
459: bool
460: MD5_Encode
461: (
462: BYTE *dst,
463: int bufsize, // ?? == numof( dst )
464: const DWORD *src,
465: int count // 4 or 2 == numof( src )
466: )
467: {
468: // パラメタの仮定
469: ASSERT( ( 2 == count )
470: || ( 4 == count ) );
471: /* ASSERT( 64 == bufsize );
472: ASSERT( 16 == bufsize / sizeof(DWORD) ); */
473:
474: {for( int i = 0; (0 < bufsize) && (i < count); ++i )
475: {
476: *dst++ = static_cast<BYTE>( 0xFF & *src );
477: if ( --bufsize <= 0 )
478: return true;
479:
480: *dst++ = static_cast<BYTE>( 0xFF & (*src >> 8) );
481: if ( --bufsize <= 0 )
482: return true;
483:
484: *dst++ = static_cast<BYTE>( 0xFF & (*src >> 16) );
485: if ( --bufsize <= 0 )
486: return true;
487:
488: *dst++ = static_cast<BYTE>( 0xFF & (*src >> 24) );
489: if ( --bufsize <= 0 )
490: return true;
491:
492: ++src;
493: }}
494:
495: return true;
496: }//MD5_Encode
497:
498: //*********************************************************
499: // MD5_Decode
500: // BYTE[64] を DWORD[16] へ変換
501: //*********************************************************
502: static
503: void
504: MD5_Decode
505: (
506: DWORD *dst,
507: int count, // 16 == numof( dst )
508: const BYTE *src,
509: int length // 64 == numof( src )
510: )
511: {
512: // パラメタの仮定
513: ASSERT( 16 == count );
514: ASSERT( 64 == length );
515: ASSERT( 16 == length / sizeof(DWORD) );
516:
517: {for( int i = 0; i < min(count, (int)(length / sizeof(DWORD))); ++i )
518: {
519: *dst++ = MD5_MAKEDWORD( src[ 0 ], src[ 1 ], src[ 2 ], src[ 3 ] );
520: src += sizeof(DWORD);
521: }}
522:
523: }//MD5_Decode
524:
525:
526: //******************************************************************************************************************
527: // TEST
528: //******************************************************************************************************************
529:
530:
531: #ifdef _DEBUG // デバッグ時のみ
532:
533:
534: //*********************************************************
535: // test_md5
536: //*********************************************************
537: DEFINE_TESTPROC( test_md5 )
538: {
539: //---------------------------------------------------------
540: // 定数 の テスト
541: //---------------------------------------------------------
542:
543: //---------------------------------------------------------
544: // ファイルスコープ関数 の テスト
545: //---------------------------------------------------------
546:
547: //---------------------------------------------------------
548: // 公開関数 の テスト
549: //---------------------------------------------------------
550:
551: static const BYTE testcase[] =
552: {
553: 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
554: 0x6E, 0x83, 0x11, 0x16, 0x8E, 0xE1, 0x6D, 0x6A, 0xA1, 0xAA, 0x48, 0xC6, 0x41, 0x45, 0x00, 0x3C,
555: 0x72, 0x68, 0x80, 0x61, 0x4B, 0x57, 0x0B, 0x40, 0xF3, 0xA3, 0x20, 0x54, 0x5A, 0xBA, 0x9E, 0x0C,
556: 0xDC, 0xF4, 0xB4, 0xC9, 0x9B, 0x82, 0xBD, 0x7D, 0xDE, 0xFE, 0xF3, 0x57, 0xE1, 0x14, 0xA2, 0x50,
557: 0xBD, 0x46, 0x96, 0xC9, 0xEE, 0x76, 0x8C, 0x32, 0x80, 0x0F, 0xDA, 0xCB, 0xBB, 0x52, 0x62, 0x89,
558: 0x42, 0x2E, 0x09, 0x1C, 0xDB, 0x70, 0x8E, 0x13, 0x6E, 0x5F, 0x62, 0x36, 0x80, 0xF5, 0x82, 0x9C,
559: 0x2E, 0x16, 0x9F, 0x4E, 0x26, 0xFA, 0x7B, 0x2A, 0x1D, 0xB9, 0xEF, 0x7C, 0x04, 0x8A, 0x7B, 0x3C,
560: 0x51, 0xE9, 0xD8, 0x5E, 0x4C, 0x2C, 0x77, 0x67, 0x75, 0x3A, 0xF9, 0xCA, 0x4F, 0xC5, 0x61, 0x43,
561: 0xEE, 0x99, 0xDC, 0x72, 0x07, 0x4C, 0x48, 0xC1, 0x13, 0x96, 0x0D, 0xF8, 0xFA, 0x57, 0xFB, 0x4C,
562: 0x37, 0x87, 0x0A, 0x08, 0xAE, 0xE8, 0x30, 0xF3, 0x6A, 0xC2, 0xFD, 0x67, 0x2B, 0xA3, 0x50, 0x3F,
563: 0xA7, 0xDF, 0x88, 0x2D, 0x25, 0xD0, 0x3E, 0x4B, 0x95, 0xC5, 0x80, 0x18, 0x25, 0x74, 0xB0, 0x5A,
564: 0xE0, 0x34, 0x88, 0x53, 0xD0, 0x6D, 0xCF, 0xD3, 0x24, 0xF8, 0x15, 0x65, 0x2E, 0xD1, 0xB3, 0xE3,
565: 0x3A, 0x3F, 0x74, 0x4D, 0x12, 0x42, 0xBB, 0x9C, 0xBB, 0x0B, 0x5F, 0x02, 0xFE, 0xA7, 0x74, 0xD3,
566: 0x3C, 0xDA, 0x1D, 0xB5, 0xAB, 0xE1, 0xA3, 0x7A, 0xDC, 0x2F, 0xD6, 0x65, 0xC9, 0xF5, 0x05, 0xF5,
567: 0xE1, 0x38, 0x4A, 0x7D, 0xF9, 0xFC, 0xD7, 0x2A, 0xF1, 0x22, 0xE0, 0x31, 0x57, 0xFE, 0x44, 0x6F,
568: 0xBD, 0xD6, 0xE8, 0x16, 0x2A, 0x58, 0xB0, 0xA7, 0x20, 0xF6, 0xD7, 0x81, 0x63, 0x8F, 0x15, 0x42,
569: 0xC8, 0xF1, 0xD9, 0xDD, 0x2B, 0x68, 0xFD, 0x3C, 0xB3, 0xC8, 0x80, 0x27, 0x85, 0xCA, 0xF4, 0xF9,
570: 0x5C, 0xE5, 0x7C, 0x57, 0xF6, 0x5E, 0xFF, 0x48, 0x05, 0xB4, 0x09, 0x7C, 0x1B, 0x9A, 0x74, 0x20,
571: 0xF2, 0xF2, 0x58, 0x15, 0x27, 0xC4, 0x85, 0x4B, 0x0A, 0x35, 0x0A, 0x8A, 0x2C, 0x0A, 0xE4, 0xA3,
572: 0xE4, 0x5D, 0xB2, 0x78, 0x22, 0xB7, 0xD7, 0xE8, 0x04, 0xA3, 0x9F, 0xC1, 0xB8, 0x1F, 0x77, 0xBE,
573: 0x60, 0xEA, 0xE1, 0x23, 0xF7, 0x27, 0x1E, 0xFC, 0xB5, 0x6F, 0xCC, 0x9B, 0x8D, 0x77, 0x06, 0x2D,
574: 0x24, 0x34, 0x0A, 0x27, 0x9B, 0x69, 0x6D, 0xD9, 0x4E, 0xF5, 0xB9, 0x3D, 0xE9, 0xBC, 0xBD, 0x53,
575: 0xD5, 0x00, 0xBB, 0x79, 0x5F, 0x7F, 0xC5, 0xCA, 0x67, 0xD4, 0xF1, 0xF1, 0x6A, 0x4D, 0x09, 0xC4,
576: 0x1E, 0x2C, 0x8A, 0x6E, 0x5E, 0xB4, 0x10, 0x4F, 0x2A, 0x07, 0xEC, 0x0B, 0x91, 0x85, 0x3F, 0x41,
577: 0x03, 0x63, 0xEC, 0x95, 0x37, 0xE0, 0xB9, 0x82, 0x75, 0x74, 0xE6, 0xC3, 0x8D, 0x65, 0xC8, 0x45,
578: 0x3C, 0xC4, 0x85, 0x3A, 0x3D, 0x0C, 0x79, 0x38, 0xEF, 0x46, 0xB8, 0x3F, 0x22, 0x0D, 0xCB, 0xEE,
579: 0x71, 0x57, 0x0F, 0x77, 0x1B, 0x47, 0x49, 0x7C, 0x93, 0x5D, 0xC1, 0x03, 0x16, 0x20, 0x9C, 0xB0,
580: 0xB1, 0xB2, 0x3C, 0xE0, 0x59, 0x6F, 0x06, 0x4D, 0x9A, 0x1B, 0xF6, 0xDB, 0xAF, 0x4C, 0x14, 0xB9,
581: 0xE6, 0x0E, 0x8A, 0x35, 0x17, 0xD5, 0xF3, 0x3C, 0xA7, 0x2F, 0x3A, 0x83, 0xCF, 0xDB, 0xA4, 0x99,
582: 0x36, 0x02, 0x80, 0x80, 0x08, 0xA2, 0xFD, 0xF2, 0x6A, 0xFB, 0x6B, 0x91, 0xE5, 0x79, 0x44, 0xB6,
583: 0xCA, 0x15, 0xC7, 0x4A, 0xD6, 0x5C, 0xA8, 0xCF, 0x9A, 0x02, 0x0D, 0x83, 0x31, 0xBD, 0xE4, 0x63,
584: 0x02, 0x8A, 0x4C, 0x5A, 0x10, 0x48, 0xC8, 0xC4, 0xC6, 0x86, 0x7C, 0xCA, 0x1D, 0xD8, 0xAB, 0x3D,
585: };
586:
587: // MD5
588: MD5_CTX *context = MD5_CreateAlgorithm();
589:
590: // 一気にハッシュ
591: {for( int i = 1; (i * MD5_HASHSIZE) < numof( testcase ); ++i )
592: {
593: MD5_InitData( context );
594: MD5_AddData( context, testcase, i * MD5_HASHSIZE );
595:
596: BYTE md5[ MD5_HASHSIZE ];
597: {for( int j = 1; j < numof( md5 ); ++j )
598: {
599: MD5_GetHash( context, md5, j );
600: VERIFY( 0 == memcmp( md5, testcase + (i * MD5_HASHSIZE), j ) );
601: }}
602: }}
603:
604: // 徐々にハッシュ
605: MD5_InitData( context );
606: {for( int i = 1; (i * MD5_HASHSIZE) < numof( testcase ); ++i )
607: {
608: {for( int j = 0; j < MD5_HASHSIZE; ++j )
609: {
610: MD5_AddData( context, &testcase[ j + ((i-1) * MD5_HASHSIZE) ], 1 );
611: }}
612:
613: BYTE md5[ MD5_HASHSIZE ];
614: MD5_GetHash( context, md5, numof( md5 ) );
615: VERIFY( 0 == memcmp( md5, testcase + (i * MD5_HASHSIZE), numof( md5 ) ) );
616: }}
617:
618: VERIFY( MD5_DestroyAlgorithm( context ) );
619: }//test_md5
620:
621:
622: #endif // #ifdef _DEBUG
623:
624:
625: //** end **
626:
627:
628: //** end **
629:
参照:
水無瀬の部屋 > sample > tools > misc > md5.cpp |
---|
このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/misc/md5_cpp.shtml