md5sum.cpp
来自「从FFMPEG转换而来的H264解码程序,VC下编译..」· C++ 代码 · 共 434 行 · 第 1/2 页
CPP
434 行
* - The function (F, G, H, or I) used to perform bitwise permutations
* on the registers,
* - The order in which values from X[] are chosen.
* - Changes to the number of bits by which the registers are rotated.
* This implementation uses a switch statement to deal with some of the
* differences between rounds. Other differences are handled by storing
* values in arrays and using the round number to select the correct set
* of values.
*
* (My implementation appears to be a poor compromise between speed, size,
* and clarity. Ugh. [crh])
*/
for( round = 0; round < 4; round++ )
{
for( i = 0; i < 16; i++ )
{
j = (4 - (i % 4)) & 0x3; /* <j> handles the rotation of ABCD. */
s = S[round][i%4]; /* <s> is the bit shift for this iteration. */
b = ABCD[(j+1) & 0x3]; /* Copy the b,c,d values per ABCD rotation. */
c = ABCD[(j+2) & 0x3]; /* This isn't really necessary, it just looks */
d = ABCD[(j+3) & 0x3]; /* clean & will hopefully be optimized away. */
/* The actual perumation function.
* This is broken out to minimize the code within the switch().
*/
switch( round )
{
case 0:
/* round 1 */
a = md5F( b, c, d ) + X[i];
break;
case 1:
/* round 2 */
a = md5G( b, c, d ) + X[ K[0][i] ];
break;
case 2:
/* round 3 */
a = md5H( b, c, d ) + X[ K[1][i] ];
break;
default:
/* round 4 */
a = md5I( b, c, d ) + X[ K[2][i] ];
break;
}
a = 0xFFFFFFFF & ( ABCD[j] + a + T[round][i] );
ABCD[j] = b + (0xFFFFFFFF & (( a << s ) | ( a >> (32 - s) )));
}
}
/* Use the stored original A, B, C, D values to perform
* one last convolution.
*/
for( i = 0; i < 4; i++ )
ABCD[i] = 0xFFFFFFFF & ( ABCD[i] + KeepABCD[i] );
} /* Permute */
/* -------------------------------------------------------------------------- **
* Functions:
*/
Tmd5::Tmd5(void)
/* ------------------------------------------------------------------------ **
* Initialize an MD5 context.
*
* Input: ctx - A pointer to the MD5 context structure to be initialized.
* Contexts are typically created thusly:
* ctx = (auth_md5Ctx *)malloc( sizeof(auth_md5Ctx) );
*
* Output: A pointer to the initialized context (same as <ctx>).
*
* Notes: The purpose of the context is to make it possible to generate
* an MD5 Message Digest in stages, rather than having to pass a
* single large block to a single MD5 function. The context
* structure keeps track of various bits of state information.
*
* Once the context is initialized, the blocks of message data
* are passed to the <auth_md5SumCtx()> function. Once the
* final bit of data has been handed to <auth_md5SumCtx()> the
* context can be closed out by calling <auth_md5CloseCtx()>,
* which also calculates the final MD5 result.
*
* Don't forget to free an allocated context structure when
* you've finished using it.
*
* See Also: <auth_md5SumCtx()>, <auth_md5CloseCtx()>
*
* ------------------------------------------------------------------------ **
*/
{
len = 0;
b_used = 0;
ABCD[0] = 0x67452301; /* The array ABCD[] contains the four 4-byte */
ABCD[1] = 0xefcdab89; /* "registers" that are manipulated to */
ABCD[2] = 0x98badcfe; /* produce the MD5 digest. The input acts */
ABCD[3] = 0x10325476; /* upon the registers, not the other way */
/* 'round. The initial values are those */
/* given in RFC 1321 (pg. 4). Note, however, that RFC 1321 */
/* provides these values as bytes, not as longwords, and the */
/* bytes are arranged in little-endian order as if they were */
/* the bytes of (little endian) 32-bit ints. That's */
/* confusing as all getout (to me, anyway). The values given */
/* here are provided as 32-bit values in C language format, */
/* so they are endian-agnostic. */
} /* auth_md5InitCtx */
void Tmd5::sum(const uint8_t *src,unsigned int len)
/* ------------------------------------------------------------------------ **
* Build an MD5 Message Digest within the given context.
*
* Input: ctx - Pointer to the context in which the MD5 sum is being
* built.
* src - A chunk of source data. This will be used to drive
* the MD5 algorithm.
* len - The number of bytes in <src>.
*
* Output: A pointer to the updated context (same as <ctx>).
*
* See Also: <auth_md5InitCtx()>, <auth_md5CloseCtx()>, <auth_md5Sum()>
*
* ------------------------------------------------------------------------ **
*/
{
/* Add the new block's length to the total length.
*/
this->len += len;
/* Copy the new block's data into the context block.
* Call the Permute() function whenever the context block is full.
*/
for(unsigned int i = 0; i < len; i++ )
{
block[ b_used ] = src[i];
b_used++;
if( 64 == b_used )
{
Permute( ABCD, block );
b_used = 0;
}
}
} /* auth_md5SumCtx */
void Tmd5::done(uint8_t dst[16])
/* ------------------------------------------------------------------------ **
* Close an MD5 Message Digest context and generate the final MD5 sum.
*
* Input: ctx - Pointer to the context in which the MD5 sum is being
* built.
* dst - A pointer to at least 16 bytes of memory, which will
* receive the finished MD5 sum.
*
* Output: A pointer to the closed context (same as <ctx>).
* You might use this to free a malloc'd context structure. :)
*
* Notes: The context (<ctx>) is returned in an undefined state.
* It must be re-initialized before re-use.
*
* See Also: <auth_md5InitCtx()>, <auth_md5SumCtx()>
*
* ------------------------------------------------------------------------ **
*/
{
int i;
uint32_t l;
/* Add the required 0x80 padding initiator byte.
* The auth_md5SumCtx() function always permutes and resets the context
* block when it gets full, so we know that there must be at least one
* free byte in the context block.
*/
block[b_used] = 0x80;
(b_used)++;
/* Zero out any remaining free bytes in the context block.
*/
for( i = b_used; i < 64; i++ )
block[i] = 0;
/* We need 8 bytes to store the length field.
* If we don't have 8, call Permute() and reset the context block.
*/
if( 56 < b_used )
{
Permute( ABCD, block );
for( i = 0; i < 64; i++ )
block[i] = 0;
}
/* Add the total length and perform the final perumation.
* Note: The 60'th byte is read from the *original* <len> value
* and shifted to the correct position. This neatly avoids
* any MAXINT numeric overflow issues.
*/
l = len << 3;
for( i = 0; i < 4; i++ )
block[56+i] |= GetLongByte( l, i );
block[60] = ((GetLongByte( len, 3 ) & 0xE0) >> 5); /* See Above! */
Permute( ABCD, block );
/* Now copy the result into the output buffer and we're done.
*/
for( i = 0; i < 4; i++ )
{
dst[ 0+i] = GetLongByte( ABCD[0], i );
dst[ 4+i] = GetLongByte( ABCD[1], i );
dst[ 8+i] = GetLongByte( ABCD[2], i );
dst[12+i] = GetLongByte( ABCD[3], i );
}
} /* auth_md5CloseCtx */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?