📄 md5.c
字号:
res_p = (char *)res_p + sizeof(md5_uint32);
hold = SWAP(md5_p->md_B);
memcpy(res_p, &hold, sizeof(md5_uint32));
res_p = (char *)res_p + sizeof(md5_uint32);
hold = SWAP(md5_p->md_C);
memcpy(res_p, &hold, sizeof(md5_uint32));
res_p = (char *)res_p + sizeof(md5_uint32);
hold = SWAP(md5_p->md_D);
memcpy(res_p, &hold, sizeof(md5_uint32));
}
/***************************** exported routines *****************************/
/*
* md5_init
*
* DESCRIPTION:
*
* Initialize structure containing state of MD5 computation. (RFC 1321,
* 3.3: Step 3). This is for progressive MD5 calculations only. If
* you have the complete string available, md5_buffer should be used.
* md5_process should be called for each bunch of bytes and after the
* last process call, md5_finish should be called to get the
* signature.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* md5_p - Pointer to md5 structure that we are initializing.
*/
void md5_init(md5_t *md5_p)
{
md5_p->md_A = 0x67452301;
md5_p->md_B = 0xefcdab89;
md5_p->md_C = 0x98badcfe;
md5_p->md_D = 0x10325476;
md5_p->md_total[0] = 0;
md5_p->md_total[1] = 0;
md5_p->md_buf_len = 0;
}
/*
* md5_process
*
* DESCRIPTION:
*
* This function is used to progressively calculate a MD5 signature some
* number of bytes at a time. If you have the complete string
* available, md5_buffer should be used. The MD5 structure should
* have been initialized with md5_init and after the last process
* call, md5_finish should be called to get the results.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* md5_p - Pointer to MD5 structure which we are progressively updating.
*
* buffer - A buffer of bytes whose MD5 signature we are calculating.
*
* buf_len - The length of the buffer.
*/
void md5_process(md5_t *md5_p, const void *buffer, const unsigned int buf_len)
{
unsigned int len = buf_len;
unsigned int in_block, add;
/*
* When we already have some bytes in our internal buffer, copy some
* from the user to fill the block.
*/
if (md5_p->md_buf_len > 0)
{
in_block = md5_p->md_buf_len;
if (in_block + len > sizeof(md5_p->md_buffer))
{
add = sizeof(md5_p->md_buffer) - in_block;
}
else
{
add = len;
}
memcpy (md5_p->md_buffer + in_block, buffer, add);
md5_p->md_buf_len += add;
in_block += add;
if (in_block > MD5_BLOCK_SIZE)
{
process_block (md5_p, md5_p->md_buffer, in_block & ~BLOCK_SIZE_MASK);
/* the regions in the following copy operation will not overlap. */
memcpy (md5_p->md_buffer,
md5_p->md_buffer + (in_block & ~BLOCK_SIZE_MASK),
in_block & BLOCK_SIZE_MASK);
md5_p->md_buf_len = in_block & BLOCK_SIZE_MASK;
}
buffer = (const char *)buffer + add;
len -= add;
}
/* process available complete blocks right from the user buffer */
if (len > MD5_BLOCK_SIZE)
{
process_block (md5_p, buffer, len & ~BLOCK_SIZE_MASK);
buffer = (const char *) buffer + (len & ~BLOCK_SIZE_MASK);
len &= BLOCK_SIZE_MASK;
}
/* copy remaining bytes into the internal buffer */
if (len > 0)
{
memcpy (md5_p->md_buffer, buffer, len);
md5_p->md_buf_len = len;
}
}
/*
* md5_finish
*
* DESCRIPTION:
*
* Finish a progressing MD5 calculation and copy the resulting MD5
* signature into the result buffer which should be 16 bytes
* (MD5_SIZE). After this call, the MD5 structure is invalid.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* md5_p - Pointer to MD5 structure which we are finishing.
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*/
void md5_finish(md5_t *md5_p, void *signature)
{
md5_uint32 bytes, hold;
int pad;
/* take yet unprocessed bytes into account */
bytes = md5_p->md_buf_len;
/*
* Count remaining bytes. Modified to do this to better avoid
* overflows in the lower word -- Gray 10/97.
*/
if (md5_p->md_total[0] > MAX_MD5_UINT32 - bytes)
{
md5_p->md_total[1]++;
md5_p->md_total[0] -= (MAX_MD5_UINT32 - bytes);
}
else
{
md5_p->md_total[0] += bytes;
}
/*
* Pad the buffer to the next MD5_BLOCK-byte boundary. (RFC 1321,
* 3.1: Step 1). We need enough room for two size words and the
* bytes left in the buffer. For some reason even if we are equal
* to the block-size, we add an addition block of pad bytes.
*/
pad = MD5_BLOCK_SIZE - (sizeof(md5_uint32) * 2) - bytes;
if (pad <= 0)
{
pad += MD5_BLOCK_SIZE;
}
/*
* Modified from a fixed array to this assignment and memset to be
* more flexible with block-sizes -- Gray 10/97.
*/
if (pad > 0)
{
/* some sort of padding start byte */
md5_p->md_buffer[bytes] = (unsigned char)0x80;
if (pad > 1)
{
memset (md5_p->md_buffer + bytes + 1, 0, pad - 1);
}
bytes += pad;
}
/* put the 64-bit file length in _bits_ (i.e. *8) at the end of the buffer */
hold = SWAP(md5_p->md_total[0] << 3);
memcpy(md5_p->md_buffer + bytes, &hold, sizeof(md5_uint32));
bytes += sizeof(md5_uint32);
/* shift the high word over by 3 and add in the top 3 bits from the low */
hold = SWAP((md5_p->md_total[1] << 3) | (md5_p->md_total[0] >> 29));
memcpy(md5_p->md_buffer + bytes, &hold, sizeof(md5_uint32));
bytes += sizeof(md5_uint32);
/* process last bytes, the padding chars, and size words */
process_block(md5_p, md5_p->md_buffer, bytes);
md5_get_result(md5_p, signature);
}
/*
* md5_buffer
*
* DESCRIPTION:
*
* This function is used to calculate a MD5 signature for a buffer of
* bytes. If you only have part of a buffer that you want to process
* then md5_init, md5_process, and md5_finish should be used.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* buffer - A buffer of bytes whose MD5 signature we are calculating.
*
* buf_len - The length of the buffer.
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*/
void md5_buffer(const char *buffer, const unsigned int buf_len, void *signature)
{
md5_t md5;
/* initialize the computation context */
md5_init(&md5);
/* process whole buffer but last buf_len % MD5_BLOCK bytes */
md5_process(&md5, buffer, buf_len);
/* put result in desired memory area */
md5_finish(&md5, signature);
}
/*
* md5_sig_to_string
*
* DESCRIPTION:
*
* Convert a MD5 signature in a 16 byte buffer into a hexadecimal string
* representation.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature - a 16 byte buffer that contains the MD5 signature.
*
* str - a string of charactes which should be at least 33 bytes long (2
* characters per MD5 byte and 1 for the \0).
*
* str_len - the length of the string.
*/
void md5_sig_to_string(void *signature, char *str, const unsigned int str_len)
{
unsigned char *sig_p;
char *str_p, *max_p;
unsigned int high, low;
str_p = str;
max_p = str + str_len;
for (sig_p = (unsigned char *)signature;
sig_p < (unsigned char *)signature + MD5_SIZE;
sig_p++)
{
high = *sig_p / 16;
low = *sig_p % 16;
/* account for 2 chars */
if (str_p + 1 >= max_p)
{
break;
}
*str_p++ = HEX_STRING[high];
*str_p++ = HEX_STRING[low];
}
/* account for 2 chars */
if (str_p < max_p)
{
*str_p++ = '\0';
}
}
/*
* md5_sig_from_string
*
* DESCRIPTION:
*
* Convert a MD5 signature from a hexadecimal string representation into
* a 16 byte buffer.
*
* RETURNS:
*
* None.
*
* ARGUMENTS:
*
* signature - A 16 byte buffer that will contain the MD5 signature.
*
* str - A string of charactes which _must_ be at least 32 bytes long (2
* characters per MD5 byte).
*/
void md5_sig_from_string(void *signature, const char *str)
{
unsigned char *sig_p;
const char *str_p;
char *hex;
unsigned int high, low, val;
hex = HEX_STRING;
sig_p = signature;
for (str_p = str; str_p < str + MD5_SIZE * 2; str_p += 2)
{
high = strchr(hex, *str_p) - hex;
low = strchr(hex, *(str_p + 1)) - hex;
val = high * 16 + low;
*sig_p++ = val;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -