md5sum.cpp
来自「从FFMPEG转换而来的H264解码程序,VC下编译..」· C++ 代码 · 共 434 行 · 第 1/2 页
CPP
434 行
/* ========================================================================== **
*
* MD5.c
*
* Copyright:
* Copyright (C) 2003, 2004 by Christopher R. Hertel
*
* Email: crh@ubiqx.mn.org
*
* Modified for use with MPlayer, detailed CVS changelog at
* http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
*
* -------------------------------------------------------------------------- **
*
* Description:
* Implements the MD5 hash algorithm, as described in RFC 1321.
*
* -------------------------------------------------------------------------- **
*
* License:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* -------------------------------------------------------------------------- **
*
* Notes:
*
* None of this will make any sense unless you're studying RFC 1321 as you
* read the code.
*
* MD5 is described in RFC 1321.
* The MD*4* algorithm is described in RFC 1320 (that's 1321 - 1).
* MD5 is very similar to MD4, but not quite similar enough to justify
* putting the two into a single module. Besides, I wanted to add a few
* extra functions to this one to expand its usability.
*
* There are three primary motivations for this particular implementation.
* 1) Programmer's pride. I wanted to be able to say I'd done it, and I
* wanted to learn from the experience.
* 2) Portability. I wanted an implementation that I knew to be portable
* to a reasonable number platforms. In particular, the algorithm is
* designed with little-endian platforms in mind, but I wanted an
* endian-agnostic implementation.
* 3) Compactness. While not an overriding goal, I thought it worth-while
* to see if I could reduce the overall size of the result. This is in
* keeping with my hopes that this library will be suitable for use in
* some embedded environments.
* Beyond that, cleanliness and clarity are always worth pursuing.
*
* As mentioned above, the code really only makes sense if you are familiar
* with the MD5 algorithm or are using RFC 1321 as a guide. This code is
* quirky, however, so you'll want to be reading carefully.
*
* Yeah...most of the comments are cut-and-paste from my MD4 implementation.
*
* -------------------------------------------------------------------------- **
*
* References:
* IETF RFC 1321: The MD5 Message-Digest Algorithm
* Ron Rivest. IETF, April, 1992
*
* ========================================================================== **
*/
#include "stdafx.h"
#include "md5sum.h" /* Added this line */
/* -------------------------------------------------------------------------- **
* Static Constants:
*
* K[][] - In round one, the values of k (which are used to index
* particular four-byte sequences in the input) are simply
* sequential. In later rounds, however, they are a bit more
* varied. Rather than calculate the values of k (which may
* or may not be possible--I haven't though about it) the
* values are stored in this array.
*
* S[][] - In each round there is a left rotate operation performed as
* part of the 16 permutations. The number of bits varies in
* a repeating patter. This array keeps track of the patterns
* used in each round.
*
* T[][] - There are four rounds of 16 permutations for a total of 64.
* In each of these 64 permutation operations, a different
* constant value is added to the mix. The constants are
* based on the sine function...read RFC 1321 for more detail.
* In any case, the correct constants are stored in the T[][]
* array. They're divided up into four groups of 16.
*/
/* -------------------------------------------------------------------------- **
* Macros:
* md5F(), md5G(), md5H(), and md5I() are described in RFC 1321.
* All of these operations are bitwise, and so not impacted by endian-ness.
*
* GetLongByte()
* Extract one byte from a (32-bit) longword. A value of 0 for <idx>
* indicates the lowest order byte, while 3 indicates the highest order
* byte.
*
*/
/* -------------------------------------------------------------------------- **
* Static Functions:
*/
void Tmd5::Permute(uint32_t ABCD[4], const uint8_t block[64])
/* ------------------------------------------------------------------------ **
* Permute the ABCD "registers" using the 64-byte <block> as a driver.
*
* Input: ABCD - Pointer to an array of four unsigned longwords.
* block - An array of bytes, 64 bytes in size.
*
* Output: none.
*
* Notes: The MD5 algorithm operates on a set of four longwords stored
* (conceptually) in four "registers". It is easy to imagine a
* simple MD4/5 chip that would operate this way. In any case,
* the mangling of the contents of those registers is driven by
* the input message. The message is chopped and finally padded
* into 64-byte chunks and each chunk is used to manipulate the
* contents of the registers.
*
* The MD5 Algorithm calls for padding the input to ensure that
* it is a multiple of 64 bytes in length. The last 16 bytes
* of the padding space are used to store the message length
* (the length of the original message, before padding, expressed
* in terms of bits). If there is not enough room for 16 bytes
* worth of bitcount (eg., if the original message was 122 bytes
* long) then the block is padded to the end with zeros and
* passed to this function. Then *another* block is filled with
* zeros except for the last 16 bytes which contain the length.
*
* Oh... and the algorithm requires that there be at least one
* padding byte. The first padding byte has a value of 0x80,
* and any others are 0x00.
*
* ------------------------------------------------------------------------ **
*/
{
static const uint8_t K[3][16] =
{
/* Round 1: skipped (since it is simply sequential). */
{ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 }, /* R2 */
{ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 }, /* R3 */
{ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 } /* R4 */
};
static const uint8_t S[4][4] =
{
{ 7, 12, 17, 22 }, /* Round 1 */
{ 5, 9, 14, 20 }, /* Round 2 */
{ 4, 11, 16, 23 }, /* Round 3 */
{ 6, 10, 15, 21 } /* Round 4 */
};
static const uint32_t T[4][16] =
{
{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 },
{ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a },
{ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* Round 3 */
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 },
{ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* Round 4 */
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 },
};
int round;
int i, j;
uint8_t s;
uint32_t a, b, c, d;
uint32_t KeepABCD[4];
uint32_t X[16];
/* Store the current ABCD values for later re-use.
*/
for( i = 0; i < 4; i++ )
KeepABCD[i] = ABCD[i];
/* Convert the input block into an array of unsigned longs, taking care
* to read the block in Little Endian order (the algorithm assumes this).
* The uint32_t values are then handled in host order.
*/
for( i = 0, j = 0; i < 16; i++ )
{
X[i] = (uint32_t)block[j++];
X[i] |= ((uint32_t)block[j++] << 8);
X[i] |= ((uint32_t)block[j++] << 16);
X[i] |= ((uint32_t)block[j++] << 24);
}
/* This loop performs the four rounds of permutations.
* The rounds are each very similar. The differences are in three areas:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?