[PR]

水無瀬の部屋 > Programming > sample > tools > misc > md5.cpp
最終更新日: 2007/03/30

   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: 

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > 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
同人ダウンロード販売
同人ダウンロード販売|DL.Getchu.com