📄 md5.c
字号:
HH( A, B, C, D, in[ 13 ], S31, mConst[ 40 ] ); /* 41 */ HH( D, A, B, C, in[ 0 ], S32, mConst[ 41 ] ); /* 42 */ HH( C, D, A, B, in[ 3 ], S33, mConst[ 42 ] ); /* 43 */ HH( B, C, D, A, in[ 6 ], S34, mConst[ 43 ] ); /* 44 */ HH( A, B, C, D, in[ 9 ], S31, mConst[ 44 ] ); /* 45 */ HH( D, A, B, C, in[ 12 ], S32, mConst[ 45 ] ); /* 46 */ HH( C, D, A, B, in[ 15 ], S33, mConst[ 46 ] ); /* 47 */ HH( B, C, D, A, in[ 2 ], S34, mConst[ 47 ] ); /* 48 */ /* Round 4 */ II( A, B, C, D, in[ 0 ], S41, mConst[ 48 ] ); /* 49 */ II( D, A, B, C, in[ 7 ], S42, mConst[ 49 ] ); /* 50 */ II( C, D, A, B, in[ 14 ], S43, mConst[ 50 ] ); /* 51 */ II( B, C, D, A, in[ 5 ], S44, mConst[ 51 ] ); /* 52 */ II( A, B, C, D, in[ 12 ], S41, mConst[ 52 ] ); /* 53 */ II( D, A, B, C, in[ 3 ], S42, mConst[ 53 ] ); /* 54 */ II( C, D, A, B, in[ 10 ], S43, mConst[ 54 ] ); /* 55 */ II( B, C, D, A, in[ 1 ], S44, mConst[ 55 ] ); /* 56 */ II( A, B, C, D, in[ 8 ], S41, mConst[ 56 ] ); /* 57 */ II( D, A, B, C, in[ 15 ], S42, mConst[ 57 ] ); /* 58 */ II( C, D, A, B, in[ 6 ], S43, mConst[ 58 ] ); /* 59 */ II( B, C, D, A, in[ 13 ], S44, mConst[ 59 ] ); /* 60 */ II( A, B, C, D, in[ 4 ], S41, mConst[ 60 ] ); /* 61 */ II( D, A, B, C, in[ 11 ], S42, mConst[ 61 ] ); /* 62 */ II( C, D, A, B, in[ 2 ], S43, mConst[ 62 ] ); /* 63 */ II( B, C, D, A, in[ 9 ], S44, mConst[ 63 ] ); /* 64 */ buf[ 0 ] += A; buf[ 1 ] += B; buf[ 2 ] += C; buf[ 3 ] += D; }#endif /* __ARC__ || IRIX || __TSC__ */#endif /* ASM_MD5 *//***************************************************************************** ** MD5 Support Routines ** *****************************************************************************/#ifdef LITTLE_ENDIAN#ifdef ASM_MD5 void longReverse( LONG *buffer, int byteCount );#else/* When run on a little-endian CPU we need to perform byte reversal on an array of longwords. It is possible to make the code endianness- independant by fiddling around with data at the byte level, but this makes for very slow code, so we rely on the user to sort out endianness at compile time */void longReverse( LONG *buffer, int byteCount ) { LONG value; byteCount /= sizeof( LONG ); while( byteCount-- ) { value = ( *buffer << 16 ) | ( *buffer >> 16 ); *buffer++ = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 ); } }#endif /* ASM_MD5 */#endif /* LITTLE_ENDIAN *//* The external buffer for saving the Mysterious Constants. Since the MD5/ MDC code is dual-use, we need to save the constants whenever we switch from MDC to MD5 */extern BYTE cryptBuffer[];/* The routine MD5SetConst sets the Mysterious Constants to either the standard MD5 ones or to a user-defined set for MDC */static BOOLEAN isMD5const = FALSE;void MD5SetConst( BYTE *buffer ) { if( buffer == NULL ) { /* If the constants are already set up, don't bother re-setting them */ if( !isMD5const ) { memcpy( mConst, md5const, MD5_ROUNDS * sizeof( LONG ) ); isMD5const = TRUE; } } else { /* Copy the values to the mConst array, with endianness conversion if necessary */ memcpy( mConst, buffer, MD5_ROUNDS * sizeof( LONG ) );#ifdef LITTLE_ENDIAN longReverse( mConst, MD5_ROUNDS * sizeof( LONG ) );#endif /* LITTLE_ENDIAN */ isMD5const = FALSE; } }/* The routine MD5Init initializes the message-digest context mdContext. All fields are set to zero */void MD5Init( MD5_CTX *mdContext ) { mdContext->i[ 0 ] = mdContext->i[ 1 ] = 0L; /* Load magic initialization constants */ mdContext->buf[ 0 ] = 0x67452301L; mdContext->buf[ 1 ] = 0xEFCDAB89L; mdContext->buf[ 2 ] = 0x98BADCFEL; mdContext->buf[ 3 ] = 0x10325476L; /* Set up the Mysterious Constants if necessary */ if( !isMD5const ) { memcpy( cryptBuffer, mConst, MD5_ROUNDS * sizeof( LONG ) ); MD5SetConst( NULL ); } }/* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[ 0 .. inLen-1 ] in the message whose digest is being computed. This is an optimized version which assumes that the buffer is a multiple of MD5_BLOCKSIZE bytes long */#ifdef __MSDOS__void MD5Update( MD5_CTX *mdContext, BYTE *buffer, unsigned int noBytes ) { int bufIndex = 0; /* Update number of bits */ if( ( mdContext->i[ 0 ] + ( ( LONG ) noBytes << 3 ) ) < mdContext->i[ 0 ] ) mdContext->i[ 1 ]++; /* Carry from low to high bitCount */ mdContext->i[ 0 ] += ( ( LONG ) noBytes << 3 ); mdContext->i[ 1 ] += ( ( LONG ) noBytes >> 29 ); /* Process data in MD5_BLOCKSIZE chunks */ while( noBytes >= MD5_BLOCKSIZE ) { MD5Transform( mdContext->buf, ( LONG * ) ( buffer + bufIndex ) ); bufIndex += MD5_BLOCKSIZE; noBytes -= MD5_BLOCKSIZE; } /* Handle any remaining bytes of data. This should only happen once on the final lot of data */ memcpy( mdContext->in, buffer + bufIndex, noBytes ); }/* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[ 0 ... 15 ] */void MD5Final( MD5_CTX *mdContext ) { int count; LONG lowBitcount = mdContext->i[ 0 ], highBitcount = mdContext->i[ 1 ]; /* Compute number of bytes mod 64 */ count = ( int ) ( ( lowBitcount >> 3 ) & 0x3F ); /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ ( ( BYTE * ) mdContext->in )[ count++ ] = 0x80; /* Pad out to 56 mod 64 */ if( count > 56 ) { /* Two lots of padding: Pad the first block to 64 bytes */ memset( ( BYTE * ) &mdContext->in + count, 0, 64 - count ); MD5Transform( mdContext->buf, ( LONG * ) mdContext->in ); /* Now fill the next block with 56 bytes */ memset( &mdContext->in, 0, 56 ); } else /* Pad block to 56 bytes */ memset( ( BYTE * ) &mdContext->in + count, 0, 56 - count );#if 0 /* Compute number of bytes mod 64 */ mdi = ( int ) ( ( mdContext->i[ 0 ] >> 3 ) & 0x3F ); padLen = ( mdi < 56 ) ? ( 56 - mdi ) : ( 120 - mdi ); /* Pad out to 56 mod 64 */ if( padLen ) { /* Set first char of padding to 0x80 */ mdContext->in[ mdi ] = 0x80; if( mdi >= 56 ) { /* Two lots of padding: Pad first block to 64 bytes, then fill next block with 56 bytes */ memset( &mdContext->in[ mdi + 1 ], 0, 63 - mdi ); MD5Transform( mdContext->buf, ( LONG * ) mdContext->in ); memset( mdContext->in, 0, 56 ); } else /* Pad block to 56 bytes */ memset( &mdContext->in[ mdi + 1 ], 0, padLen - 1 ); } if( mdi + padLen == 64 ) MD5Transform( mdContext->buf, ( LONG * ) mdContext->in );#endif /* 0 */ /* Append length in bits and transform */ ( ( LONG * ) mdContext->in )[ 14 ] = lowBitcount; ( ( LONG * ) mdContext->in )[ 15 ] = highBitcount; MD5Transform( mdContext->buf, ( LONG * ) mdContext->in ); /* Store buffer in digest */ memcpy( mdContext->digest, mdContext->buf, 16 ); /* Restore the previous Mysterious Constants */ memcpy( mConst, cryptBuffer, MD5_ROUNDS * sizeof( LONG ) ); isMD5const = FALSE; }#elsevoid MD5Update( MD5_CTX *mdContext, BYTE *inBuf, unsigned int inLen ) { int mdi; LONG in[ 16 ]; unsigned int i, ii; /* Compute number of bytes mod 64 */ mdi = ( int ) ( ( mdContext->i[ 0 ] >> 3 ) & 0x3F ); /* Update number of bits */ if( ( mdContext->i[ 0 ] + ( ( LONG ) inLen << 3 ) ) < mdContext->i[ 0 ] ) mdContext->i[ 1 ]++; /* Carry from low to high bitCount */ mdContext->i[ 0 ] += ( ( LONG ) inLen << 3 ); mdContext->i[ 1 ] += ( ( LONG ) inLen >> 29 ); while( inLen-- ) { /* Add new character to buffer, increment mdi */ mdContext->in[ mdi++ ] = *inBuf++; /* Transform if necessary */ if( mdi == 0x40 ) { for( i = 0, ii = 0; i < 16; i++, ii += 4 ) in[ i ] = ( ( ( LONG ) mdContext->in[ ii + 3 ] ) << 24 ) | \ ( ( ( LONG ) mdContext->in[ ii + 2 ] ) << 16 ) | \ ( ( ( LONG ) mdContext->in[ ii + 1 ] ) << 8 ) | \ ( ( LONG ) mdContext->in[ ii ] ); MD5Transform( mdContext->buf, in ); mdi = 0; } } }/* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[ 0 ... 15 ] */void MD5Final( MD5_CTX *mdContext ) { int mdi, padLen; BYTE padding[ 64 ]; unsigned int i, ii; LONG in[ 16 ]; /* Save number of bits */ in[ 14 ] = mdContext->i[ 0 ]; in[ 15 ] = mdContext->i[ 1 ]; /* Compute number of bytes mod 64 */ mdi = ( int ) ( ( mdContext->i[ 0 ] >> 3 ) & 0x3F ); /* Pad out to 56 mod 64 */ padLen = ( mdi < 56 ) ? ( 56 - mdi ) : ( 120 - mdi ); padding[ 0 ] = 0x80; memset( padding + 1, 0, padLen - 1 ); MD5Update( mdContext, padding, padLen ); /* Append length in bits and transform */ for( i = 0, ii = 0; i < 14; i++, ii += 4 ) in[ i ] = ( ( ( LONG ) mdContext->in[ ii + 3 ] ) << 24 ) | \ ( ( ( LONG ) mdContext->in[ ii + 2 ] ) << 16 ) | \ ( ( ( LONG ) mdContext->in[ ii + 1 ] ) << 8 ) | \ ( ( LONG ) mdContext->in[ ii ] ); MD5Transform( mdContext->buf, in ); /* Store buffer in digest */ for( i = 0, ii = 0; i < 4; i++, ii += 4 ) { mdContext->digest[ ii ] = ( BYTE ) ( mdContext->buf[ i ] & 0xFF ); mdContext->digest[ ii + 1 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 8 ) & 0xFF ); mdContext->digest[ ii + 2 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 16 ) & 0xFF ); mdContext->digest[ ii + 3 ] = ( BYTE ) ( ( mdContext->buf[ i ] >> 24 ) & 0xFF ); } /* Restore the previous Mysterious Constants */ memcpy( mConst, cryptBuffer, MD5_ROUNDS * sizeof( LONG ) ); isMD5const = FALSE; }#endif /* !__MSDOS__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -