MD5算法之C#实现
md5 算法分片计算 c语言

md5 算法分片计算 c语言MD5算法是一种广泛使用的哈希函数,它可以将任意长度的消息作为输入,产生一个128位(16字节)的哈希值作为输出。
在C 语言中,我们可以使用MD5算法对数据进行分片计算,以下是一个简单的示例:c.#include <stdio.h>。
#include <string.h>。
#include <openssl/md5.h>。
void calculate_md5(const char data, size_t data_len, unsigned char md5_sum) {。
MD5_CTX context;MD5_Init(&context);MD5_Update(&context, data, data_len);MD5_Final(md5_sum, &context);}。
int main() {。
const char data = "Hello, MD5!";unsigned char md5_sum[MD5_DIGEST_LENGTH];calculate_md5(data, strlen(data), md5_sum);printf("MD5 sum: ");for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {。
printf("%02x", md5_sum[i]);}。
printf("\n");return 0;}。
在这个示例中,我们使用了OpenSSL库中提供的MD5函数来计算MD5哈希值。
首先,我们定义了一个`calculate_md5`函数,它接受输入数据、数据长度和一个指向存储MD5哈希值的缓冲区的指针。
然后,在`main`函数中,我们调用`calculate_md5`函数来计算给定数据的MD5哈希值,并打印输出结果。
C#中算法

C#使用MD5算法对密码进行加密对密码进行加密的算法有很多种,在C#中较常使用的是MD5加密算法。
它是一种用于产生数字签名的单项散列算法,具体代码如下:public string Encrypt(string strPwd){MD5 md5 = new MD5CryptoServiceProvider();byte[] data = System.Text.Encoding.Default.GetBytes(strPwd);//将字符编码为一个字节序列byte[] md5data = puteHash(data);//计算data字节数组的哈希值md5.Clear();string str = "";for (int i = 0; i <md5data.Length-1; i++){str += md5data[i].ToString("x").PadLeft(2,'0');}return str;}注意:在编码之前应先引入命名空间System.Security.Cryptography。
而且始用散列算法对原始密码加密后无法再恢复。
这也是MD5加密算法的一个蔽端。
C#实现二、八、十六进制数转十进制数的算法二进制换为十进制的方法,例如:二进制数:11001十进制数:1*24+1*23+0*22+0*21+1*20=25八进制换为十进制的方法,例如:八进制数:32007十进制数:3*84+2*83+0*82+0*81+7*80=13319十六进制换为十进制的方法,例如:十六进制数:a20f(由于十六进制数用a~f表示10~15之间的数,所以计算时将a~f用10~15表示)十进制数:10*83+2*82+0*81+15*80=41487通过以上二、八、十六进制数转十进制数的计算方法,可得出计算的代码为://参数Num为需要转换的数,n为该数的进制public string ToD(string Num, int n){char[] nums=Num.ToCharArray ();int d = 0;for (int i = 0; i <nums.Length ; i++){string number=nums [i].ToString ();if (n == 16){switch (number.ToUpper ()){case "A":number = "10";break;case "B":number = "11";break;case "C":number = "12";break;case "D":number = "13";break;case "E":number = "14";break;case "F":number = "15";break;}}Double power = Math.Pow(Convert.ToDouble (n),Convert.ToDouble ( nums.Length - (i +1)));d = d + Convert.ToInt32 (number) * Convert.ToInt32 (power);}return d.ToString ();}C#十进制数转十六进制数的算法十进数转换为十六进制数的方法与以上两种的转换方法相似,不同之处除了除数改为16外,还需要将余数为10~15的数改为A~F的形式。
MD5加密C语言实现

MD5加密C语言实现MD5 (Message Digest Algorithm 5) 是一种常用的密码散列函数,用于将数据加密为128位长度的摘要。
在C语言中,可以通过一系列步骤来实现MD5加密算法。
1.准备工作:首先需要包含一些C标准头文件和预定义常量。
在C语言中,可以使用以下代码来实现:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdint.h>#define HASH_LENGTH 16```2.定义数据结构:MD5算法涉及到一个64字节的消息块和一个4字节的消息摘要块。
在C语言中,可以使用以下代码来定义这些结构:```ctypedef structuint8_t data[64];uint32_t datalen;uint32_t bitlen[2];uint32_t state[4];}MD5_CTX;typedef uint8_t (*hash_function)(uint8_t *);```3.定义常量和函数:MD5算法使用到一些常量和函数。
在C语言中,可以使用以下代码来定义这些常量和函数:```cconst uint32_t k[64] =// more constants ...};const uint32_t r[64] =7,12,17,22,7,12,17,22,// more constants ...};void md5_transform(MD5_CTX *ctx, uint8_t data[]);void md5_init(MD5_CTX *ctx)ctx->datalen = 0;ctx->bitlen[0] = 0;ctx->bitlen[1] = 0;ctx->state[1] = 0xEFCDAB89;ctx->state[2] = 0x98BADCFE;void md5_update(MD5_CTX *ctx, uint8_t data[], uint32_t len) for (uint32_t i = 0; i < len; i++)ctx->data[ctx->datalen] = data[i];ctx->datalen++;if (ctx->datalen == 64)md5_transform(ctx, ctx->data);ctx->bitlen[0] += 512;ctx->bitlen[1] += (ctx->bitlen[0] < 512);ctx->datalen = 0;}}void md5_final(MD5_CTX *ctx, uint8_t hash[])uint32_t i = ctx->datalen;if (ctx->datalen < 56)ctx->data[i++] = 0x80;while (i < 56)ctx->data[i++] = 0x00;}} elsectx->data[i++] = 0x80;while (i < 64)ctx->data[i++] = 0x00;}md5_transform(ctx, ctx->data);memset(ctx->data, 0, 56);}ctx->bitlen[0] += ctx->datalen * 8;ctx->bitlen[1] += (ctx->bitlen[0] < ctx->datalen * 8); ctx->data[63] = ctx->bitlen[0] & 0xff;ctx->data[62] = (ctx->bitlen[0] >> 8) & 0xff;ctx->data[61] = (ctx->bitlen[0] >> 16) & 0xff;ctx->data[60] = (ctx->bitlen[0] >> 24) & 0xff;ctx->data[59] = ctx->bitlen[1] & 0xff;ctx->data[58] = (ctx->bitlen[1] >> 8) & 0xff;ctx->data[57] = (ctx->bitlen[1] >> 16) & 0xff;ctx->data[56] = (ctx->bitlen[1] >> 24) & 0xff;md5_transform(ctx, ctx->data);for (i = 0; i < 4; i++)hash[i] = (ctx->state[0] >> (i * 8)) & 0xff;hash[i + 4] = (ctx->state[1] >> (i * 8)) & 0xff;hash[i + 8] = (ctx->state[2] >> (i * 8)) & 0xff;hash[i + 12] = (ctx->state[3] >> (i * 8)) & 0xff;}void md5_transform(MD5_CTX *ctx, uint8_t data[])uint32_t a, b, c, d, f, g, temp;uint32_t m[16], i, j;for (i = 0, j = 0; i < 16; i++, j += 4)m[i] = (data[j]) + (data[j + 1] << 8) + (data[j + 2] << 16) + (data[j + 3] << 24);}a = ctx->state[0];b = ctx->state[1];c = ctx->state[2];d = ctx->state[3];for (i = 0; i < 64; i++)if (i < 16)f=(b&c),((~b)&d);g=i;} else if (i < 32)f=(d&b),((~d)&c);g=(5*i+1)%16;} else if (i < 48)f=b^c^d;g=(3*i+5)%16;} elsef=c^(b,(~d));g=(7*i)%16;}temp = d;d=c;c=b;b = b + leftrotate((a + f + k[i] + m[g]), r[i]);a = temp;}ctx->state[0] += a;ctx->state[1] += b;ctx->state[2] += c;ctx->state[3] += d;```4.实现加密函数:最后,可以编写一个简单的调用MD5算法的加密函数。
C语言实现MD5算法

C语言实现MD5算法MD5(Message-Digest Algorithm 5)是一种常用的哈希函数算法,广泛用于验证数据完整性、密码存储和数字证书等领域。
下面是使用C语言实现MD5算法的代码。
这段代码包含了MD5算法的各个步骤,包括初始化MD5结构体、填充数据、更新状态、计算摘要等。
```c#include <stdio.h>#include <stdint.h>#include <string.h>//定义MD5常量#define B 0xEFCDAB89#define C 0x98BADCFE//循环左移宏定义#define LEFT_ROTATE(x, n) (((x) << (n)) , ((x) >> (32-(n)))) //填充消息void padMessage(uint8_t *message, uint32_t length)//计算需要填充的字节数uint32_t padLength = (length % sizeof(uint32_t) == 56) ? 64 : 56;padLength = padLength - (length % sizeof(uint32_t));//填充1位1message[length++] = 0x80;//填充0位for (uint32_t i = 0; i < padLength; i++) message[length++] = 0x00;}//在消息末尾添加原始消息的长度(以位表示)for (uint32_t i = 0; i < sizeof(uint32_t); i++) message[length++] = (length << 3) >> (i * 8); }//初始化MD5结构体void initMD5(uint32_t *state)state[0] = A;state[1] = B;state[2] = C;state[3] = D;//更新状态void updateState(uint32_t *state, uint32_t *M)uint32_t A = state[0], B = state[1], C = state[2], D = state[3];//定义MD5循环运算函数#define MD5_FUNCTION(a, b, c, d, k, s, i) \a=b+LEFT_ROTATE((a+F(b,c,d)+M[k]+T[i]),s)//迭代压缩消息MD5_FUNCTION(A,B,C,D,0,7,1);MD5_FUNCTION(D,A,B,C,1,12,2);MD5_FUNCTION(C,D,A,B,2,17,3);MD5_FUNCTION(B,C,D,A,3,22,4);MD5_FUNCTION(A,B,C,D,4,7,5);MD5_FUNCTION(D,A,B,C,5,12,6);MD5_FUNCTION(C,D,A,B,6,17,7);MD5_FUNCTION(B,C,D,A,7,22,8);MD5_FUNCTION(A,B,C,D,8,7,9);MD5_FUNCTION(D,A,B,C,9,12,10);MD5_FUNCTION(C,D,A,B,10,17,11);MD5_FUNCTION(B,C,D,A,11,22,12);MD5_FUNCTION(A,B,C,D,12,7,13);MD5_FUNCTION(C,D,A,B,14,17,15); MD5_FUNCTION(B,C,D,A,15,22,16); MD5_FUNCTION(A,B,C,D,1,5,17); MD5_FUNCTION(D,A,B,C,6,9,18); MD5_FUNCTION(C,D,A,B,11,14,19); MD5_FUNCTION(B,C,D,A,0,20,20); MD5_FUNCTION(A,B,C,D,5,5,21); MD5_FUNCTION(D,A,B,C,10,9,22); MD5_FUNCTION(C,D,A,B,15,14,23); MD5_FUNCTION(B,C,D,A,4,20,24); MD5_FUNCTION(A,B,C,D,9,5,25); MD5_FUNCTION(D,A,B,C,14,9,26); MD5_FUNCTION(C,D,A,B,3,14,27); MD5_FUNCTION(B,C,D,A,8,20,28); MD5_FUNCTION(A,B,C,D,13,5,29); MD5_FUNCTION(D,A,B,C,2,9,30); MD5_FUNCTION(C,D,A,B,7,14,31); MD5_FUNCTION(B,C,D,A,12,20,32);MD5_FUNCTION(D,A,B,C,8,11,34); MD5_FUNCTION(C,D,A,B,11,16,35); MD5_FUNCTION(B,C,D,A,14,23,36); MD5_FUNCTION(A,B,C,D,1,4,37); MD5_FUNCTION(D,A,B,C,4,11,38); MD5_FUNCTION(C,D,A,B,7,16,39); MD5_FUNCTION(B,C,D,A,10,23,40); MD5_FUNCTION(A,B,C,D,13,4,41); MD5_FUNCTION(D,A,B,C,0,11,42); MD5_FUNCTION(C,D,A,B,3,16,43); MD5_FUNCTION(B,C,D,A,6,23,44); MD5_FUNCTION(A,B,C,D,9,4,45); MD5_FUNCTION(D,A,B,C,12,11,46); MD5_FUNCTION(C,D,A,B,15,16,47); MD5_FUNCTION(B,C,D,A,2,23,48); MD5_FUNCTION(A,B,C,D,0,6,49); MD5_FUNCTION(D,A,B,C,7,10,50); MD5_FUNCTION(C,D,A,B,14,15,51);MD5_FUNCTION(A,B,C,D,12,6,53); MD5_FUNCTION(D,A,B,C,3,10,54); MD5_FUNCTION(C,D,A,B,10,15,55); MD5_FUNCTION(B,C,D,A,1,21,56); MD5_FUNCTION(A,B,C,D,8,6,57); MD5_FUNCTION(D,A,B,C,15,10,58); MD5_FUNCTION(C,D,A,B,6,15,59); MD5_FUNCTION(B,C,D,A,13,21,60); MD5_FUNCTION(A,B,C,D,4,6,61); MD5_FUNCTION(D,A,B,C,11,10,62); MD5_FUNCTION(C,D,A,B,2,15,63); MD5_FUNCTION(B,C,D,A,9,21,64); #undef MD5_FUNCTION//更新状态state[0] += A;state[1] += B;state[2] += C;state[3] += D;//计算MD5摘要void md5(uint8_t *message, uint32_t length, uint32_t *digest) //初始化MD5结构体uint32_t state[4];initMD5(state);//填充消息padMessage(message, length);//计算消息分组数量uint32_t numOfBlocks = length / 64;//处理每个分组for (uint32_t i = 0; i < numOfBlocks; i++)uint32_t M[16];memcpy(M, message + (i * 64), 64);//更新状态updateState(state, M);}//获取MD5摘要memcpy(digest, state, 16);int mai//测试用例uint8_t message[] = "Hello, MD5!";uint32_t length = sizeof(message) - 1;//计算MD5摘要uint32_t digest[4];md5(message, length, digest);//输出摘要printf("MD5 Digest: ");for (int i = 0; i < 4; i++)printf("%02x", ((uint8_t*)digest)[i]);}printf("\n");return 0;```以上是使用C语言实现MD5算法的代码。
C语言计算MD5

C语⾔计算MD5 #include <stdio.h>#include <string.h>#include <stdint.h>#define u8 uint8_t#define u32 uint32_t#define u64 uint64_t#define MD5_DIGEST_SIZE 16#define MD5_HMAC_BLOCK_SIZE 64#define MD5_BLOCK_WORDS 16#define MD5_HASH_WORDS 4#define F1(x, y, z) (z ^ (x & (y ^ z)))#define F2(x, y, z) F1(z, x, y)#define F3(x, y, z) (x ^ y ^ z)#define F4(x, y, z) (y ^ (x | ~z))#define MD5STEP(f, w, x, y, z, in, s) (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) struct md5_ctx {u32 hash[MD5_HASH_WORDS];u32 block[MD5_BLOCK_WORDS];u64 byte_count;};static void md5_transform(u32 *hash, u32 const *in) {u32 a, b, c, d;a = hash[0];b = hash[1];c = hash[2];d = hash[3];MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);hash[0] += a;hash[1] += b;hash[2] += c;hash[3] += d;}static void md5_transform_helper(struct md5_ctx *ctx) {md5_transform(ctx->hash, ctx->block);}static void md5_init(void *ctx) {struct md5_ctx *mctx = ctx;mctx->hash[0] = 0x67452301;mctx->hash[1] = 0xefcdab89;mctx->hash[2] = 0x98badcfe;mctx->hash[3] = 0x10325476;mctx->byte_count = 0;}static void md5_update(void *ctx, const u8 *data, unsigned int len) {struct md5_ctx *mctx = ctx;const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);mctx->byte_count += len;if (avail > len) {memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, len); return;}memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail); md5_transform_helper(mctx);data += avail;len -= avail;while (len >= sizeof(mctx->block)) {memcpy(mctx->block, data, sizeof(mctx->block));md5_transform_helper(mctx);data += sizeof(mctx->block);len -= sizeof(mctx->block);}memcpy(mctx->block, data, len);}static void md5_final(void *ctx, u8 *out) {struct md5_ctx *mctx = ctx;const unsigned int offset = mctx->byte_count & 0x3f;char *p = (char *)mctx->block + offset;int padding = 56 - (offset + 1);*p++ = 0x80;if (padding < 0) {memset(p, 0x00, padding + sizeof (u64));md5_transform_helper(mctx);p = (char *)mctx->block;padding = 56;}memset(p, 0, padding);mctx->block[14] = mctx->byte_count << 3;mctx->block[15] = mctx->byte_count >> 29;md5_transform(mctx->hash, mctx->block);memcpy(out, mctx->hash, sizeof(mctx->hash)); memset(mctx, 0, sizeof(*mctx));}int main(int argc, char *argv[]) {uint8_t buffer[32];uint8_t out[MD5_DIGEST_SIZE];strcpy(buffer, "hello");struct md5_ctx mctx;md5_init(&mctx);md5_update(&mctx, buffer, strlen("hello")); md5_final(&mctx, out);printf("hello md5 is:\n");for(int i = 0; i < MD5_DIGEST_SIZE; i++) {printf("%02X", out[i]);}printf("\n");return 0;}。
MD5加密算法原理及实现

MD5加密算法原理及实现MD5消息摘要算法,属Hash算法⼀类。
MD5算法对输⼊任意长度的消息进⾏运⾏,产⽣⼀个128位的消息摘要。
以下所描述的消息长度、填充数据都以位(Bit)为单位,字节序为⼩端字节。
算法原理1、数据填充对消息进⾏数据填充,使消息的长度对512取模得448,设消息长度为X,即满⾜X mod 512=448。
根据此公式得出需要填充的数据长度。
填充⽅法:在消息后⾯进⾏填充,填充第⼀位为1,其余为0。
2、添加消息长度在第⼀步结果之后再填充上原消息的长度,可⽤来进⾏的存储长度为64位。
如果消息长度⼤于264,则只使⽤其低64位的值,即(消息长度对 264取模)。
在此步骤进⾏完毕后,最终消息长度就是512的整数倍。
3、数据处理准备需要⽤到的数据:4个常数:A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z)); H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));把消息分以512位为⼀分组进⾏处理,每⼀个分组进⾏4轮变换,以上⾯所说4个常数为起始变量进⾏计算,重新输出4个变量,以这4个变量再进⾏下⼀分组的运算,如果已经是最后⼀个分组,则这4个变量为最后的结果,即MD5值。
具体计算的实现较为复杂,建议查阅相关书籍,下⾯给出在C++上的实现代码。
代码实现#MD5.h1 #ifndef MD5H2#define MD5H3 #include <math.h>4 #include <Windows.h>56void ROL(unsigned int &s, unsigned short cx); //32位数循环左移实现函数7void ltob(unsigned int &i); //B\L互转,接受UINT类型8 unsigned int* MD5(const char* mStr); //接⼝函数,并执⾏数据填充,计算MD5时调⽤此函数910#endif#MD5.cpp1 #include "MD5.h"23/*4组计算函数*/4 inline unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)5 {6return (X & Y) | ((~X) & Z);7 }8 inline unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)9 {10return (X & Z) | (Y & (~Z));11 }12 inline unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)13 {14return X ^ Y ^ Z;15 }16 inline unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)17 {18return Y ^ (X | (~Z));19 }20/*4组计算函数结束*/2122/*32位数循环左移实现函数*/23void ROL(unsigned int &s, unsigned short cx)24 {25if (cx > 32)cx %= 32;26 s = (s << cx) | (s >> (32 - cx));27return;28 }2930/*B\L互转,接收UINT类型*/31void ltob(unsigned int &i)32 {33 unsigned int tmp = i;//保存副本34byte *psour = (byte*)&tmp, *pdes = (byte*)&i;35 pdes += 3;//调整指针,准备左右调转36for (short i = 3; i >= 0; --i)37 {38 CopyMemory(pdes - i, psour + i, 1);39 }40return;41 }4243/*44MD5循环计算函数,label=第⼏轮循环(1<=label<=4),lGroup数组=4个种⼦副本,M=数据(16组32位数指针)45种⼦数组排列⽅式: --A--D--C--B--,即 lGroup[0]=A; lGroup[1]=D; lGroup[2]=C; lGroup[3]=B;46*/47void AccLoop(unsigned short label, unsigned int *lGroup, void *M)48 {49 unsigned int *i1, *i2, *i3, *i4, TAcc, tmpi = 0; //定义:4个指针; T表累加器;局部变量50 typedef unsigned int(*clac)(unsigned int X, unsigned int Y, unsigned int Z); //定义函数类型51const unsigned int rolarray[4][4] = {52 { 7, 12, 17, 22 },53 { 5, 9, 14, 20 },54 { 4, 11, 16, 23 },55 { 6, 10, 15, 21 }56 };//循环左移-位数表57const unsigned short mN[4][16] = {58 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },59 { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },60 { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },61 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }62 };//数据坐标表63const unsigned int *pM = static_cast<unsigned int*>(M);//转换类型为32位的Uint64 TAcc = ((label - 1) * 16) + 1; //根据第⼏轮循环初始化T表累加器65 clac clacArr[4] = { F, G, H, I }; //定义并初始化计算函数指针数组6667/*⼀轮循环开始(16组->16次)*/68for (short i = 0; i < 16; ++i)69 {70/*进⾏指针⾃变换*/71 i1 = lGroup + ((0 + i) % 4);72 i2 = lGroup + ((3 + i) % 4);73 i3 = lGroup + ((2 + i) % 4);74 i4 = lGroup + ((1 + i) % 4);7576/*第⼀步计算开始: A+F(B,C,D)+M[i]+T[i+1] 注:第⼀步中直接计算T表*/77 tmpi = (*i1 + clacArr[label - 1](*i2, *i3, *i4) + pM[(mN[label - 1][i])] + (unsigned int)(0x100000000UL * abs(sin((double)(TAcc + i)))));78 ROL(tmpi, rolarray[label - 1][i % 4]);//第⼆步:循环左移79 *i1 = *i2 + tmpi;//第三步:相加并赋值到种⼦80 }81return;82 }8384/*接⼝函数,并执⾏数据填充*/85 unsigned int* MD5(const char* mStr)86 {87 unsigned int mLen = strlen(mStr); //计算字符串长度88if (mLen < 0) return0;89 unsigned int FillSize = 448 - ((mLen * 8) % 512); //计算需填充的bit数90 unsigned int FSbyte = FillSize / 8; //以字节表⽰的填充数91 unsigned int BuffLen = mLen + 8 + FSbyte; //缓冲区长度或者说填充后的长度92 unsigned char *md5Buff = new unsigned char[BuffLen]; //分配缓冲区93 CopyMemory(md5Buff, mStr, mLen); //复制字符串到缓冲区9495/*数据填充开始*/96 md5Buff[mLen] = 0x80; //第⼀个bit填充197 ZeroMemory(&md5Buff[mLen + 1], FSbyte - 1); //其它bit填充0,另⼀可⽤函数为FillMemory98 unsigned long long lenBit = mLen * 8ULL; //计算字符串长度,准备填充99 CopyMemory(&md5Buff[mLen + FSbyte], &lenBit, 8); //填充长度100/*数据填充结束*/101102/*运算开始*/103 unsigned int LoopNumber = BuffLen / 64; //以16个字为⼀分组,计算分组数量104 unsigned int A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;//初始4个种⼦,⼩端类型105 unsigned int *lGroup = new unsigned int[4]{ A, D, C, B}; //种⼦副本数组,并作为返回值返回106for (unsigned int Bcount = 0; Bcount < LoopNumber; ++Bcount) //分组⼤循环开始107 {108/*进⼊4次计算的⼩循环*/109for (unsigned short Lcount = 0; Lcount < 4;)110 {111 AccLoop(++Lcount, lGroup, &md5Buff[Bcount * 64]);112 }113/*数据相加作为下⼀轮的种⼦或者最终输出*/114 A = (lGroup[0] += A);115 B = (lGroup[3] += B);116 C = (lGroup[2] += C);117 D = (lGroup[1] += D);118 }119/*转换内存中的布局后才能正常显⽰*/120 ltob(lGroup[0]);121 ltob(lGroup[1]);122 ltob(lGroup[2]);123 ltob(lGroup[3]);124 delete[] md5Buff; //清除内存并返回125return lGroup;126 }再给出调⽤实例(以win32控制台应⽤程序为例):#main.cpp1 #include <iostream>2 #include <string.h>3 #include <stdlib.h>4 #include "MD5.h"56int main(int argc, char **argv)7 {8char tmpstr[256], buf[4][10];9 std::cout << "请输⼊要加密的字符串:";10 std::cin >> tmpstr;11 unsigned int* tmpGroup = MD5(tmpstr);12 sprintf_s(buf[0], "%8X", tmpGroup[0]);13 sprintf_s(buf[1], "%8X", tmpGroup[3]);14 sprintf_s(buf[2], "%8X", tmpGroup[2]);15 sprintf_s(buf[3], "%8X", tmpGroup[1]);16 std::cout <<"MD5:"<< buf[0] << buf[1] << buf[2] << buf[3] << std::endl; 1718 delete[] tmpGroup;19return0; //在此下断点才能看到输出的值20 }注:以上代码在VS2013上编译通过。
基于51单片机MD5算法实现

基于51单片机MD5算法实现MD5算法是一种广泛使用的密码散列函数,其输出为128位的散列值。
这种算法在计算简单、辅助和速度方面的优点使其被广泛应用于许多领域,如密码学、数据完整性验证和数字签名等。
在本文中,我们将基于51单片机实现MD5算法。
首先,我们需要了解MD5算法的基本原理。
MD5算法主要包括四个步骤:填充、初始向量、处理和输出。
在填充步骤中,我们将输入消息的长度进行填充,以保证其长度是64的倍数。
在初始向量步骤中,我们初始化了4个32位的寄存器:A、B、C和D。
在处理步骤中,我们通过对输入消息进行分组,并进行一系列的位运算来生成散列值。
最后,在输出步骤中,我们将A、B、C、D寄存器的内容连接起来,形成128位的散列值。
在51单片机中,我们可以使用C语言来实现MD5算法。
首先,我们需要定义一些辅助函数来处理字节和位的运算。
以下是一些关键函数的实现示例:-`F`函数:根据输入的X、Y和Z值进行位运算,并返回结果。
-`G`函数:根据输入的X、Y和Z值进行位运算,并返回结果。
-`H`函数:根据输入的X、Y和Z值进行位运算,并返回结果。
-`I`函数:根据输入的X、Y和Z值进行位运算,并返回结果。
- `shift_left`函数:将输入值向左循环移动给定的位数。
-`FF`函数等:定义了一系列的辅助函数来进行特定的位运算。
接下来,我们需要实现MD5算法的核心函数。
以下是MD5算法的一般实现示例:1.初始化MD缓冲区,包括A、B、C、D寄存器的初始值。
2.对输入消息进行填充,并将其分成512位的块。
3.对每个块执行一系列的位运算,包括旋转、移位、与、或等操作。
4.将寄存器的内容连接起来,形成128位的散列值。
在51单片机中实现MD5算法需要注意的是内存和处理速度的限制。
因为51单片机的存储容量较低,因此对于大型输入消息,可能需要进行分块处理和多次运算。
此外,由于单片机处理速度较低,可能需要优化代码以提高执行效率。
C计算文件MD5值

MD5ChecksumDefines.h1.//Magic initialization constants2.#define MD5_INIT_STATE_0 0x674523013.#define MD5_INIT_STATE_1 0xefcdab894.#define MD5_INIT_STATE_2 0x98badcfe5.#define MD5_INIT_STATE_3 0x103254766.7.//Constants for Transform routine.8.#define MD5_S11 79.#define MD5_S12 1210.#define MD5_S13 1711.#define MD5_S14 2212.#define MD5_S21 513.#define MD5_S22 914.#define MD5_S23 1415.#define MD5_S24 2016.#define MD5_S31 417.#define MD5_S32 1118.#define MD5_S33 1619.#define MD5_S34 2320.#define MD5_S41 621.#define MD5_S42 1022.#define MD5_S43 1523.#define MD5_S44 2124.25.//Transformation Constants - Round 126.#define MD5_T01 0xd76aa478 //Transformation Constant 127.#define MD5_T02 0xe8c7b756 //Transformation Constant 228.#define MD5_T03 0x242070db //Transformation Constant 329.#define MD5_T04 0xc1bdceee //Transformation Constant 430.#define MD5_T05 0xf57c0faf //Transformation Constant 531.#define MD5_T06 0x4787c62a //Transformation Constant 632.#define MD5_T07 0xa8304613 //Transformation Constant 733.#define MD5_T08 0xfd469501 //Transformation Constant 834.#define MD5_T09 0x698098d8 //Transformation Constant 935.#define MD5_T10 0x8b44f7af //Transformation Constant 1036.#define MD5_T11 0xffff5bb1 //Transformation Constant 1137.#define MD5_T12 0x895cd7be //Transformation Constant 1238.#define MD5_T13 0x6b901122 //Transformation Constant 1339.#define MD5_T14 0xfd987193 //Transformation Constant 1440.#define MD5_T15 0xa679438e //Transformation Constant 1541.#define MD5_T16 0x49b40821 //Transformation Constant 1642.43.//Transformation Constants - Round 245.#define MD5_T18 0xc040b340 //Transformation Constant 1846.#define MD5_T19 0x265e5a51 //Transformation Constant 1947.#define MD5_T20 0xe9b6c7aa //Transformation Constant 2048.#define MD5_T21 0xd62f105d //Transformation Constant 2149.#define MD5_T22 0x02441453 //Transformation Constant 2250.#define MD5_T23 0xd8a1e681 //Transformation Constant 2351.#define MD5_T24 0xe7d3fbc8 //Transformation Constant 2452.#define MD5_T25 0x21e1cde6 //Transformation Constant 2553.#define MD5_T26 0xc33707d6 //Transformation Constant 2654.#define MD5_T27 0xf4d50d87 //Transformation Constant 2755.#define MD5_T28 0x455a14ed //Transformation Constant 2856.#define MD5_T29 0xa9e3e905 //Transformation Constant 2957.#define MD5_T30 0xfcefa3f8 //Transformation Constant 3058.#define MD5_T31 0x676f02d9 //Transformation Constant 3159.#define MD5_T32 0x8d2a4c8a //Transformation Constant 3260.61.//Transformation Constants - Round 362.#define MD5_T33 0xfffa3942 //Transformation Constant 3363.#define MD5_T34 0x8771f681 //Transformation Constant 3464.#define MD5_T35 0x6d9d6122 //Transformation Constant 3565.#define MD5_T36 0xfde5380c //Transformation Constant 3666.#define MD5_T37 0xa4beea44 //Transformation Constant 3767.#define MD5_T38 0x4bdecfa9 //Transformation Constant 3868.#define MD5_T39 0xf6bb4b60 //Transformation Constant 3969.#define MD5_T40 0xbebfbc70 //Transformation Constant 4070.#define MD5_T41 0x289b7ec6 //Transformation Constant 4171.#define MD5_T42 0xeaa127fa //Transformation Constant 4272.#define MD5_T43 0xd4ef3085 //Transformation Constant 4373.#define MD5_T44 0x04881d05 //Transformation Constant 4474.#define MD5_T45 0xd9d4d039 //Transformation Constant 4575.#define MD5_T46 0xe6db99e5 //Transformation Constant 4676.#define MD5_T47 0x1fa27cf8 //Transformation Constant 4777.#define MD5_T48 0xc4ac5665 //Transformation Constant 4878.79.//Transformation Constants - Round 480.#define MD5_T49 0xf4292244 //Transformation Constant 4981.#define MD5_T50 0x432aff97 //Transformation Constant 5082.#define MD5_T51 0xab9423a7 //Transformation Constant 5183.#define MD5_T52 0xfc93a039 //Transformation Constant 5284.#define MD5_T53 0x655b59c3 //Transformation Constant 5385.#define MD5_T54 0x8f0ccc92 //Transformation Constant 5486.#define MD5_T55 0xffeff47d //Transformation Constant 5587.#define MD5_T56 0x85845dd1 //Transformation Constant 5689.#define MD5_T58 0xfe2ce6e0 //Transformation Constant 5890.#define MD5_T59 0xa3014314 //Transformation Constant 5991.#define MD5_T60 0x4e0811a1 //Transformation Constant 6092.#define MD5_T61 0xf7537e82 //Transformation Constant 6193.#define MD5_T62 0xbd3af235 //Transformation Constant 6294.#define MD5_T63 0x2ad7d2bb //Transformation Constant 6395.#define MD5_T64 0xeb86d391 //Transformation Constant 6496.97.98.//Null data (except for first BYTE) used to finalise the checksum calculation99.static unsigned char PADDING[64] = {100. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0103.};CMD5Checksum.h[cpp]1.#if !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)2.#define AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_3.4.#if _MSC_VER > 10005.#pragma once6.#endif // _MSC_VER > 10007./*****************************************************************************************8.9.10.*****************************************************************************************/11.class CMD5Checksum12.{13.public:14.static CString GetMD5OfString(CString strString);15.//interface functions for the RSA MD5 calculation16.static CString GetMD5(const CString& strFilePath);17.18.protected:19.//constructor/destructor20. CMD5Checksum();21.virtual ~CMD5Checksum() {};22.23.//RSA MD5 implementation24.void Transform(BYTE Block[64]);25.void Update(BYTE* Input, ULONG nInputLen);26. CString Final();27.inline DWORD RotateLeft(DWORD x, int n);28.inline void FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);29.inline void GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);30.inline void HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);31.inline void II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);32.33.//utility functions34.inline void DWordToByte(BYTE* Output, DWORD* Input, UINT nLength);35.inline void ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength);36.37.private:38.BYTE m_lpszBuffer[64]; //input buffer39.ULONG m_nCount[2]; //number of bits, modulo 2^64 (lsb first)40.ULONG m_lMD5[4]; //MD5 checksum41.};42.43.#endif // !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)MD5Checksum.cpp[cpp]1.#include "stdafx.h"2.#include "MD5Checksum.h"3.#include "MD5ChecksumDefines.h"4.5.#ifdef _DEBUG6.#undef THIS_FILE7.static char THIS_FILE[]=__FILE__;8.#define new DEBUG_NEW9.#endif10.11.12./*****************************************************************************************13.*************/15.CString CMD5Checksum::GetMD5(const CString& strFilePath)16.{17.try18. {19. CFile file;20.if(file.Open(strFilePath,CFile::modeRead)==0)21.return _T("");22.23. CMD5Checksum MD5Checksum; //checksum object24.int nLength = 0; //number of bytes read from the file25.const int nBufferSize = 1024; //checksum the file in blocks of 1024bytes26.BYTE Buffer[nBufferSize]; //buffer for data read from the file27.28.//checksum the file in blocks of 1024 bytes29.while ((nLength = file.Read( Buffer, nBufferSize )) > 0 )30. {31. MD5Checksum.Update( Buffer, nLength );32. }33.34. file.Close();35.36.//finalise the checksum and return it37.return MD5Checksum.Final();38. }39.40.//report any file exceptions in debug mode only41.catch (CFileException* e )42. {43. TRACE0("CMD5Checksum::GetMD5: CFileException caught");44.throw e;45. }46.}47.48./*****************************************************************************************49.FUNCTION: CMD5Checksum::RotateLeft50.DETAILS: private51.DESCRIPTION: Rotates the bits in a 32 bit DWORD left by a specified amount52.RETURNS: The rotated DWORD53.ARGUMENTS: DWORD x : the value to be rotated54.int n : the number of bits to rotate by*************/56.DWORD CMD5Checksum::RotateLeft(DWORD x, int n)57.{58.//check that DWORD is 4 bytes long - true in Visual C++ 6 and 32 bit Windows59. ASSERT( sizeof(x) == 4 );60.61.//rotate and return x62.return (x << n) | (x >> (32-n));63.}64.65.66./*****************************************************************************************67.FUNCTION: CMD5Checksum::FF68.DETAILS: protected69.DESCRIPTION: Implementation of basic MD5 transformation algorithm70.RETURNS: none71.ARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum72.DWORD X : Input data73.DWORD S : MD5_SXX Transformation constant74.DWORD T : MD5_TXX Transformation constant75.NOTES: None76.*****************************************************************************************/77.void CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)78.{79.DWORD F = (B & C) | (~B & D);80. A += F + X + T;81. A = RotateLeft(A, S);82. A += B;83.}84.85.86./*****************************************************************************************87.FUNCTION: CMD5Checksum::GG88.DETAILS: protected89.DESCRIPTION: Implementation of basic MD5 transformation algorithm90.RETURNS: none91.ARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum92.DWORD X : Input data93.DWORD S : MD5_SXX Transformation constant94.DWORD T : MD5_TXX Transformation constant95.NOTES: None96.*****************************************************************************************/97.void CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)98.{99.DWORD G = (B & D) | (C & ~D);100. A += G + X + T;101. A = RotateLeft(A, S);102. A += B;103.}104.105.106./************************************************************************** ***************107.FUNCTION: CMD5Checksum::HH108.DETAILS: protected109.DESCRIPTION: Implementation of basic MD5 transformation algorithm110.RETURNS: none111.ARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum112.DWORD X : Input data113.DWORD S : MD5_SXX Transformation constant114.DWORD T : MD5_TXX Transformation constant115.NOTES: None116.*************************************************************************** **************/117.void CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)118.{119.DWORD H = (B ^ C ^ D);120. A += H + X + T;121. A = RotateLeft(A, S);122. A += B;123.}124.125.126./************************************************************************** ***************127.FUNCTION: CMD5Checksum::II128.DETAILS: protected129.DESCRIPTION: Implementation of basic MD5 transformation algorithm130.RETURNS: none131.ARGUMENTS: DWORD &A, B, C, D : Current (partial) checksum132.DWORD X : Input data133.DWORD S : MD5_SXX Transformation constant134.DWORD T : MD5_TXX Transformation constant135.NOTES: None136.*************************************************************************** **************/137.void CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T)138.{139.DWORD I = (C ^ (B | ~D));140. A += I + X + T;141. A = RotateLeft(A, S);142. A += B;143.}144.145.146./************************************************************************** ***************147.FUNCTION: CMD5Checksum::ByteToDWord148.DETAILS: private149.DESCRIPTION: Transfers the data in an 8 bit array to a 32 bit array150.RETURNS: void151.ARGUMENTS: DWORD* Output : the 32 bit (unsigned long) destination array 152.BYTE* Input : the 8 bit (unsigned char) source array153.UINT nLength : the number of 8 bit data items in the source array154.NOTES: Four BYTES from the input array are transferred to each DWORD entr y155.of the output array. The first BYTE is transferred to the bits (0-7)156.of the output DWORD, the second BYTE to bits 8-15 etc.157.The algorithm assumes that the input array is a multiple of 4 bytes long 158.so that there is a perfect fit into the array of 32 bit words.159.*************************************************************************** **************/160.void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength) 161.{162.//entry invariants163. ASSERT( nLength % 4 == 0 );164. ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) );165. ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );166.167.//initialisations168.UINT i=0; //index to Output array169.UINT j=0; //index to Input array170.171.//transfer the data by shifting and copying172.for ( ; j < nLength; i++, j += 4)173. {174. Output[i] = (ULONG)Input[j] |175. (ULONG)Input[j+1] << 8 |176. (ULONG)Input[j+2] << 16 |177. (ULONG)Input[j+3] << 24;178. }179.}180.181./************************************************************************** ***************182.FUNCTION: CMD5Checksum::Transform183.DETAILS: protected184.DESCRIPTION: MD5 basic transformation algorithm; transforms 'm_lMD5' 185.RETURNS: void186.ARGUMENTS: BYTE Block[64]187.NOTES: An MD5 checksum is calculated by four rounds of 'Transformation'. 188.The MD5 checksum currently held in m_lMD5 is merged by the189.transformation process with data passed in 'Block'.190.*************************************************************************** **************/191.void CMD5Checksum::Transform(BYTE Block[64])192.{193.//initialise local data with current checksum194.ULONG a = m_lMD5[0];195.ULONG b = m_lMD5[1];196.ULONG c = m_lMD5[2];197.ULONG d = m_lMD5[3];198.199.//copy BYTES from input 'Block' to an array of ULONGS 'X'200.ULONG X[16];201. ByteToDWord( X, Block, 64 );202.203.//Perform Round 1 of the transformation204. FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01);205. FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02);206. FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03);207. FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04);208. FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05);209. FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06);210. FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07);211. FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08);212. FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09); 213. FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10); 214. FF (c, d, a, b, X[10], MD5_S13, MD5_T11); 215. FF (b, c, d, a, X[11], MD5_S14, MD5_T12); 216. FF (a, b, c, d, X[12], MD5_S11, MD5_T13); 217. FF (d, a, b, c, X[13], MD5_S12, MD5_T14); 218. FF (c, d, a, b, X[14], MD5_S13, MD5_T15); 219. FF (b, c, d, a, X[15], MD5_S14, MD5_T16); 220.221.//Perform Round 2 of the transformation 222. GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); 223. GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); 224. GG (c, d, a, b, X[11], MD5_S23, MD5_T19); 225. GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); 226. GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); 227. GG (d, a, b, c, X[10], MD5_S22, MD5_T22); 228. GG (c, d, a, b, X[15], MD5_S23, MD5_T23); 229. GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); 230. GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); 231. GG (d, a, b, c, X[14], MD5_S22, MD5_T26); 232. GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); 233. GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); 234. GG (a, b, c, d, X[13], MD5_S21, MD5_T29); 235. GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); 236. GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); 237. GG (b, c, d, a, X[12], MD5_S24, MD5_T32); 238.239.//Perform Round 3 of the transformation 240. HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); 241. HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); 242. HH (c, d, a, b, X[11], MD5_S33, MD5_T35); 243. HH (b, c, d, a, X[14], MD5_S34, MD5_T36); 244. HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37); 245. HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38); 246. HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); 247. HH (b, c, d, a, X[10], MD5_S34, MD5_T40); 248. HH (a, b, c, d, X[13], MD5_S31, MD5_T41); 249. HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); 250. HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); 251. HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); 252. HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); 253. HH (d, a, b, c, X[12], MD5_S32, MD5_T46); 254. HH (c, d, a, b, X[15], MD5_S33, MD5_T47); 255. HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48);256.257.//Perform Round 4 of the transformation258. II (a, b, c, d, X[ 0], MD5_S41, MD5_T49);259. II (d, a, b, c, X[ 7], MD5_S42, MD5_T50);260. II (c, d, a, b, X[14], MD5_S43, MD5_T51);261. II (b, c, d, a, X[ 5], MD5_S44, MD5_T52);262. II (a, b, c, d, X[12], MD5_S41, MD5_T53);263. II (d, a, b, c, X[ 3], MD5_S42, MD5_T54);264. II (c, d, a, b, X[10], MD5_S43, MD5_T55);265. II (b, c, d, a, X[ 1], MD5_S44, MD5_T56);266. II (a, b, c, d, X[ 8], MD5_S41, MD5_T57);267. II (d, a, b, c, X[15], MD5_S42, MD5_T58);268. II (c, d, a, b, X[ 6], MD5_S43, MD5_T59);269. II (b, c, d, a, X[13], MD5_S44, MD5_T60);270. II (a, b, c, d, X[ 4], MD5_S41, MD5_T61);271. II (d, a, b, c, X[11], MD5_S42, MD5_T62);272. II (c, d, a, b, X[ 2], MD5_S43, MD5_T63);273. II (b, c, d, a, X[ 9], MD5_S44, MD5_T64);274.275.//add the transformed values to the current checksum276. m_lMD5[0] += a;277. m_lMD5[1] += b;278. m_lMD5[2] += c;279. m_lMD5[3] += d;280.}281.282.283./************************************************************************** ***************284.CONSTRUCTOR: CMD5Checksum285.DESCRIPTION: Initialises member data286.ARGUMENTS: None287.NOTES: None288.*************************************************************************** **************/289.CMD5Checksum::CMD5Checksum()290.{291.// zero members292. memset( m_lpszBuffer, 0, 64 );293. m_nCount[0] = m_nCount[1] = 0;294.295.// Load magic state initialization constants296. m_lMD5[0] = MD5_INIT_STATE_0;297. m_lMD5[1] = MD5_INIT_STATE_1;298. m_lMD5[2] = MD5_INIT_STATE_2;299. m_lMD5[3] = MD5_INIT_STATE_3;300.}301.302./************************************************************************** ***************303.FUNCTION: CMD5Checksum::DWordToByte304.DETAILS: private305.DESCRIPTION: Transfers the data in an 32 bit array to a 8 bit array306.RETURNS: void307.ARGUMENTS: BYTE* Output : the 8 bit destination array308.DWORD* Input : the 32 bit source array309.UINT nLength : the number of 8 bit data items in the source array310.NOTES: One DWORD from the input array is transferred into four BYTES 311.in the output array. The first (0-7) bits of the first DWORD are312.transferred to the first output BYTE, bits bits 8-15 are transferred from 313.the second BYTE etc.314.315.The algorithm assumes that the output array is a multiple of 4 bytes long 316.so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs.317.*************************************************************************** **************/318.void CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength ) 319.{320.//entry invariants321. ASSERT( nLength % 4 == 0 );322. ASSERT( AfxIsValidAddress(Output, nLength, TRUE) );323. ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) );324.325.//transfer the data by shifting and copying326.UINT i = 0;327.UINT j = 0;328.for ( ; j < nLength; i++, j += 4)329. {330. Output[j] = (UCHAR)(Input[i] & 0xff );331. Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);332. Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);333. Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff);334. }335.}336.337.338./************************************************************************** ***************339.FUNCTION: CMD5Checksum::Final340.DETAILS: protected341.DESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checks um calculation.342.RETURNS: CString : the final hexadecimal MD5 checksum result343.ARGUMENTS: None344.NOTES: Performs the final MD5 checksum calculation ('Update' does most of the work,345.this function just finishes the calculation.)346.*************************************************************************** **************/347.CString CMD5Checksum::Final()348.{349.//Save number of bits350.BYTE Bits[8];351. DWordToByte( Bits, m_nCount, 8 );352.353.//Pad out to 56 mod 64.354.UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f);355.UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);356. Update( PADDING, nPadLen );357.358.//Append length (before padding)359. Update( Bits, 8 );360.361.//Store final state in 'lpszMD5'362.const int nMD5Size = 16;363. unsigned char lpszMD5[ nMD5Size ];364. DWordToByte( lpszMD5, m_lMD5, nMD5Size );365.366.//Convert the hexadecimal checksum to a CString367. CString strMD5;368.for ( int i=0; i < nMD5Size; i++)369. {370. CString Str;371.if (lpszMD5[i] == 0)372. {373. Str = CString("00");374. }375.else if (lpszMD5[i] <= 15)376. {377. Str.Format(_T("0%X"),lpszMD5[i]);378. }379.else381. Str.Format(_T("%X"),lpszMD5[i]);382. }383.384. ASSERT( Str.GetLength() == 2 );385. strMD5 += Str;386. }387. ASSERT( strMD5.GetLength() == 32 );388.return strMD5;389.}390.391.392./************************************************************************** ***************393.FUNCTION: CMD5Checksum::Update394.DETAILS: protected395.DESCRIPTION: Implementation of main MD5 checksum algorithm396.RETURNS: void397.ARGUMENTS: BYTE* Input : input block398.UINT nInputLen : length of input block399.NOTES: Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input'400.*************************************************************************** **************/401.void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen )402.{403.//Compute number of bytes mod 64404.UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F);405.406.//Update number of bits407.if ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) )408. {409. m_nCount[1]++;410. }411. m_nCount[1] += (nInputLen >> 29);412.413.//Transform as many times as possible.414.UINT i=0;415.UINT nPartLen = 64 - nIndex;416.if (nInputLen >= nPartLen)417. {418. memcpy( &m_lpszBuffer[nIndex], Input, nPartLen );419. Transform( m_lpszBuffer );420.for (i = nPartLen; i + 63 < nInputLen; i += 64)422. Transform( &Input[i] );423. }424. nIndex = 0;425. }426.else427. {428. i = 0;429. }430.431.// Buffer remaining input432. memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);433.}434.435.436.437.CString CMD5Checksum::GetMD5OfString(CString strString)438.{439.try440. {441. CMD5Checksum MD5Checksum; //checksum object442.int nLength = strString.GetLength(); //number of bytes read f rom the file443.//const int nBufferSize = 1024; //checksum the file in blocks of 1024 bytes444.BYTE *Buffer; //buffer for data read from the file445. Buffer=(BYTE*)(strString.GetBuffer(nLength));446.//checksum the file in blocks of 1024 bytes447.//while ((nLength = File.Read( Buffer, nBufferSize )) > 0 )448.//{449. MD5Checksum.Update( Buffer, nLength );450.//}451.//finalise the checksum and return it452.return MD5Checksum.Final();453. }454.455.//report any file exceptions in debug mode only456.catch (CFileException* e )457. {458. TRACE0("CMD5Checksum::GetMD5: CFileException caught");459.throw e;460. }461.}调用的地方:[cpp]1.m_strFileMD5 = CMD5Checksum::GetMD5(m_strFilePath);。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 MD5 ("abc") = 900150983cd24fb0d6963digest") = f96b697d7cb7938d525a2f31aaf161d0 MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f MD5 ("123456789012345678901234567890123456789012345678901234567890123456789 01234567890") = 57edf4a22be3c955ac49da2e2107b67a MD5 算法之 C#程序 MD5 算法比较特别,最适合用汇编语言来写,好多高级语言对之无能无力或效率极低。 比如我最开始尝试用 Python 和 Euphoria 编写,发现不太容易。相比而言,C#作为 C 家簇 中新兴的一门.net 语言,功能比较全面。花了一晚上的工夫终于用 C#最先实现了 MD5。 主要是由于对算法的一些细节不太注意,结果输出总是不对,调试了好长时间。 //源文件:md5.cs // MD5 Alogrithm // by rufi 2004.6.20 / using System; using System.Collections; using System.IO; public class MD5 { //static state variables private static UInt32 A; private static UInt32 B; private static UInt32 C; private static UInt32 D; //number of bits to rotate in tranforming private const int S11 = 7; private const int S12 = 12; private const int S13 = 17; private const int S14 = 22; private const int S21 = 5; private const int S22 = 9; private const int S23 = 14; private const int S24 = 20; private const int S31 = 4; private const int S32 = 11; private const int S33 = 16; private const int S34 = 23; private const int S41 = 6; private const int S42 = 10; private const int S43 = 15;
有四个 32 位整数变量 (A,B,C,D) 用来计算信息摘要,每一个变量被初始化成以下 以十六进制数表示的数值,低位的字节在前面。 word A: 01 23 45 67 word B: 89 ab cd ef word C: fe dc ba 98 word D: 76 54 32 10 ※注意低位的字节在前面指的是 Little Endian 平台上内存中字节的排列方式, 而在程序中书写时,要写成: A=0x67452301 B=0xefcdab89 C=0x98badcfe D=0x10325476 第四步,定义四个 MD5 基本的按位操作函数: X,Y,Z 为 32 位整数。 F(X,Y,Z) = (X and Y) or (not(X) and Z) G(X,Y,Z) = (X and Z) or (Y and not(Z)) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X or not(Z)) 再定义四个分别用于四轮变换的函数。 设 Mj 表 示 消 息 的 第 j 个 子 分 组 ( 从 0 到 15 ), <<FF(a,b,c,d,Mj,s,ti) 表 示 a=b+((a+(F(b,c,d)+Mj+ti)<<GG(a,b,c,d,Mj,s,ti) 表 示 a=b+((a+(G(b,c,d)+Mj+ti)<<HH(a,b,c,d,Mj,s,ti) 表 示 a=b+((a+(H(b,c,d)+Mj+ti)<<II(a,b,c,d,Mj,s,ti)表示 a=b+((a+(I(b,c,d)+Mj+ti)<< 第五步,对输入数据作变换。 处理数据,N 是总的字节数,以 64 个字节为一组,每组作一次循环,每次循环进行四轮操 作。 要变换的 64 个字节用 16 个 32 位的整数数组 M[0 ...15]表示。而数组 T[1 ... 64]表示一组常 数, T[i]为 4294967296*abs(sin(i))的 32 位整数部分,i 的单位是弧度,i 的取值从 1 到 64。 具体过程如下: /* 设置主循环变量 */ For i = 0 to N/16-1 do /*每循环一次,把数据原文存放在 16 个元素的数组 X 中. */ For j = 0 to 15 do Set X[j] to M[i*16+j]. end /结束对 J 的循环 /* Save A as AA, B as BB, C as CC, and D as DD. */ AA = A BB = B CC = C DD = D /* 第 1 轮*/ /* 以 [abcd k s i]表示如下操作
MD5 算法描述 当我要写一个 MD5 算法的程序时,发现中英文的语言描述都有一些不确切的地方,某些个 细节 讲得不清楚,或者说很费解。最后不得不拿出 C 语言的源程序来调试,这对于理解算法是 很不 利的。于是就总结了一下我摸索到的一些要点。 1.来历 MD5 的全称是 message-digest algorithm 5(信息-摘要算法,在 90 年代初由 mit laboratory for computer science 和 rsa data security inc 的 ronald l. rivest 开发出来, 经 md2 、md3 和 md4 发展而来。 /rfc/rfc1321.txt ,是一份最权威的文 档, 由 ronald l. rivest 在 1992 年 8 月向 ieft 提交。 2.用途 MD5 的作用是对一段信息(message)生成信息摘要(message-digest),该摘要对该信息具有 唯一性,可以作为数字签名。用于验证文件的有效性(是否有丢失或损坏的数据),对用户 密码的加密,在哈希函数中计算散列值。 3.特点 输入一个任意长度的字节串,生成一个 128 位的整数。由于算法的某些不可逆特征,在加 密应用 上有较好的安全性。并且,MD5 算法的使用不需要支付任何版权费用。 4.说明 唯一性和不可逆性都不是绝对的,从理论上分析是一种多对一的关系,但两个不同的信息 产生 相同摘要的概率很小。不可逆是指从输出反推输入所需的运算量和计算时间太大,使用穷 搜字 典的方法又需要太多的存储空间。 5.算法描述 算法输入是一个字节串,每个字节是 8 个 bit. 算法的执行分为以下几个步骤: 第一步,补位: MD5 算法先对输入的数据进行补位,使得数据的长度(以 byte 为单位)对 64 求余的结果是 56。 即数据扩展至 LEN=K*64+56 个字节,K 为整数。 补位方法:补一个 1,然后补 0 至满足上述要求。相当于补一个 0x80 的字节,再补值 为 0 的字节。这一步里总共补充的字节数为 0~63 个。 第二步,附加数据长度: 用一个 64 位的整数表示数据的原始长度(以 bit 为单位), 将这个数字的 8 个字节按低位的在 前, 高位在后的顺序附加在补位后的数据后面。这时,数据被填补后的总长度为: LEN = K*64+56+8=(K+1)*64 Bytes。 ※注意那个 64 位整数是输入数据的原始长度而不是填充字节后的长度 ,我就在这里栽了跟 头. 第三步,初始化 MD5 参数:
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ /* Do the following 16 operations. */ [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] /* 第 2 轮* */ /* 以 [abcd k s i]表示如下操作 a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ /* Do the following 16 operations. */ [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28] [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32] /* 第 3 轮*/ /* 以 [abcd k s i]表示如下操作 a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ /* Do the following 16 operations. */ [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36] [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48] /* 第 4 轮*/ /* 以 [abcd k s i]表示如下操作 a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ /* Do the following 16 operations. */ [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] /* 然后进行如下操作 */ A = A + AA B = B + BB C = C + CC D = D + DD Next i /* 结束对 I 的循环*/ 第六步,输出结果。 A,B,C,D 连续存放,共 16 个字节,128 位。按十六进制依次输出这个 16 个字节。 最后,用程序语言实现算法后,可以输入以下几个信息对程序作一个简单的测试, 看看程序有没有错误。 MD5 ("") = d41d8cd98f00b204e9800998ecf8427e