❶ 国密算法
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
国家密码管理局公布的公钥算法,其加密强度为256位
SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。
分组密码算法(DES和SM4)、将明文数据按固定长度进行分组,然后在同一密钥控制下逐组进行加密,
公钥密码算法(RSA和SM2)、公开加密算法本身和公开公钥,保存私钥
摘要算法(SM3 md5) 这个都比较熟悉,用于数字签名,消息认证,数据完整性,但是sm3安全度比md5高
总得来说国密算法的安全度比较高,2010年12月推出,也是国家安全战略,现在银行都要要求国际算法改造,要把国际算法都给去掉
C 语言实现
https://github.com/guan/GmSSL/
Go 语言
https://github.com/tjfoc/gmsm
https://github.com/ZZMarquis/gm
Java 语言
https://github.com/PopezLotado/SM2Java
Go语言实现,调用 gmsm
❷ 求生成MD5码的c或c++代码
自己用c语言写的简单的MD5算法实现。
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
typedef unsigned char BYTE;
typedef unsigned int UINT;
typedef UINT MD5_SUB_ARRAY[16];
typedef UINT MD5_TRANSORM_FUNC(UINT,UINT,UINT);
typedef struct
{
UINT a;
UINT b;
UINT c;
UINT d;
MD5_SUB_ARRAY sub_array;
}MD5_TRANSFORM_PARAM;
const double MAX_INT = (double)0xFFFFFFFF + 1.0;
const UINT MD5_TRANSFORM_MATRIX[4][16][3] =
{
{
{ 0, 7, 1}, { 1,12, 2}, { 2,17, 3}, { 3,22, 4},
{ 4, 7, 5}, { 5,12, 6}, { 6,17, 7}, { 7,22, 8},
{ 8, 7, 9}, { 9,12,10}, {10,17,11}, {11,22,12},
{12, 7,13}, {13,12,14}, {14,17,15}, {15,22,16},
},
{
{ 1, 5,17}, { 6, 9,18}, {11,14,19}, { 0,20,20},
{ 5, 5,21}, {10, 9,22}, {15,14,23}, { 4,20,24},
{ 9, 5,25}, {14, 9,26}, { 3,14,27}, { 8,20,28},
{13, 5,29}, { 2, 9,30}, { 7,14,31}, {12,20,32},
},
{
{5, 4, 33}, { 8,11,34}, {11,16,35},{14, 23,36},
{1, 4, 37}, { 4,11,38}, { 7,16,39},{10, 23,40},
{13,4, 41}, { 0,11,42}, { 3,16,43},{ 6, 23,44},
{9, 4, 45}, {12,11,46}, {15,16,47},{ 2, 23,48},
},
{
{ 0,6,49}, { 7,10,50}, {14,15,51},{ 5, 21,52},
{12,6,53}, { 3,10,54}, {10,15,55},{ 1, 21,56},
{ 8,6,57}, {15,10,58}, { 6,15,59},{13, 21,60},
{ 4,6,61}, {11,10,62}, { 2,15,63},{ 9, 21,64},
},
};
static UINT MD5_TRANSFORM_ARRAY[65];
void MD5_Init()
{
int x;
for(x = 1; x <= 64; x++)
{
MD5_TRANSFORM_ARRAY[x] = (UINT)(MAX_INT * fabs(sin(x)));
}
}
UINT F(UINT x,UINT y,UINT z)
{
return ((x & y) | ((~x) & z));
}
UINT G(UINT x,UINT y,UINT z)
{
return ((x & z) | (y & (~z)));
}
UINT H(UINT x,UINT y,UINT z)
{
return (x ^ y ^ z);
}
UINT I(UINT x,UINT y,UINT z)
{
return (y ^ (x | (~z)));
}
BYTE* MD5_prepare_data(const BYTE* data,int len,int* new_len)
{
int rest,fill,size;
BYTE* new_data;
UINT bit_len;
// (1) 字节补齐
rest = len % 56;
if (rest <= 56) fill = 56 - rest;
else fill = (64 - rest) + 56;
new_data = (BYTE*)malloc(len + fill + 8);
if (NULL == new_data) return NULL;
if (len > 0) memcpy(new_data,data,len);
if (fill > 0) memset(new_data + len,0x80,1);
if (fill > 1) memset(new_data + len + 1,0,fill - 1);
size = fill + len;
// (2) 附加数据的比特长度
bit_len = len * 8;
// (64位二进制数表示的)比特长度的低32位
memset(new_data + size + 0,(bit_len & 0x000000FF), 1);
memset(new_data + size + 1,(bit_len & 0x0000FF00) >> 8, 1);
memset(new_data + size + 2,(bit_len & 0x00FF0000) >> 16,1);
memset(new_data + size + 3,(bit_len & 0xFF000000) >> 24,1);
// 不考虑比特长度超出32位无符号数表示范围,所以高32位总是0
memset(new_data + size + 4,0,4);
*new_len = size + 8;
return new_data;
}
void MD5_transform(MD5_TRANSFORM_PARAM* param,int ring,MD5_TRANSORM_FUNC func)
{
UINT a,b,c,d,s,k,i;
UINT abcd[4];
UINT *X,*T;
int index;
abcd[0] = param->a;
abcd[1] = param->b;
abcd[2] = param->c;
abcd[3] = param->d;
X = param->sub_array;
T = MD5_TRANSFORM_ARRAY;
for(index = 0; index < 16; index++)
{
a = abcd[(3 * index + 0) % 4];
b = abcd[(3 * index + 1) % 4];
c = abcd[(3 * index + 2) % 4];
d = abcd[(3 * index + 3) % 4];
k = MD5_TRANSFORM_MATRIX[ring][index][0];
s = MD5_TRANSFORM_MATRIX[ring][index][1];
i = MD5_TRANSFORM_MATRIX[ring][index][2];
a = a + func(b,c,d) + X[k] + T[i];
a = ( a << s) | ( a >> (32 - s)); // 循环左移
a = a + b;
abcd[(3 * index + 0) % 4] = a;
}
param->a = abcd[0];
param->b = abcd[1];
param->c = abcd[2];
param->d = abcd[3];
}
int MD5(const BYTE* data,int len)
{
int x,y,new_len;
MD5_TRANSFORM_PARAM param;
UINT AA,BB,CC,DD;
BYTE* buf;
MD5_Init();
buf = MD5_prepare_data(data,len,&new_len);
if (buf == NULL) return -1;
AA = 0x67452301;
BB = 0xefcdab89;
CC = 0x98badcfe;
DD = 0x10325476;
for(x = 0; x < new_len / 64; x++)
{
param.a = AA;
param.b = BB;
param.c = CC;
param.d = DD;
for(y = 0; y < 16; y++)
{
param.sub_array[y] = buf[64 * x + 4 * y + 0];
param.sub_array[y] += buf[64 * x + 4 * y + 1] << 8;
param.sub_array[y] += buf[64 * x + 4 * y + 2] << 16;
param.sub_array[y] += buf[64 * x + 4 * y + 3] << 24;
}
MD5_transform(¶m,0,F);
MD5_transform(¶m,1,G);
MD5_transform(¶m,2,H);
MD5_transform(¶m,3,I);
AA += param.a;
BB += param.b;
CC += param.c;
DD += param.d;
}
printf("MD5(\"%s\")=",data);
printf("%02X%02X%02X%02X",
(AA & 0x000000FF),
(AA & 0x0000FF00) >> 8,
(AA & 0x00FF0000) >> 16,
(AA & 0xFF000000) >> 24);
printf("%02X%02X%02X%02X",
(BB & 0x000000FF),
(BB & 0x0000FF00) >> 8,
(BB & 0x00FF0000) >> 16,
(BB & 0xFF000000) >> 24);
printf("%02X%02X%02X%02X",
(CC & 0x000000FF),
(CC & 0x0000FF00) >> 8,
(CC & 0x00FF0000) >> 16,
(CC & 0xFF000000) >> 24);
printf("%02X%02X%02X%02X",
(DD & 0x000000FF),
(DD & 0x0000FF00) >> 8,
(DD & 0x00FF0000) >> 16,
(DD & 0xFF000000) >> 24);
printf("\n");
return 0;
}
int main()
{
MD5("",0);
MD5("a",1);
MD5("abc",3);
MD5("message digest",14);
MD5("abcdefghijklmnopqrstuvwxyz",26);
return 0;
}
❸ 用c语言实现python的md5功能
题中所示代码中,python实现了计算空字符串的MD5值,并对MD5的值的十六进制的字符串所表示的字节进行BASE64处理。
不像Python内部有实现md5功能,根据ANSI C标准,C语言的标准库里是没有md5功能的;
但是RFC1231规定了MD5功能的C实现并提供了附件,可以直接用,也可以直接获取现成的实现,在编译链接时指定正确的.h头文件和.lib静态链接库文件;
这里我采取前者的做法(电脑上没有装VC,有VC就简单很多,使用的是minGW)大概六七百行代码左右。
然后这里展示不完,给个实现效果图
BASE64的编码原理
❹ C语言求文件MD5的函数用法
C语言没有内置的MD5函数,可以在以下页面找到C语言实现程序和MD5的算法介绍:
http://tools.ietf.org/html/rfc1321
❺ md5是什么 如何计算MD5
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。
MD5算法具有以下特点:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的16进制数字串)。
大家都知道,地球上任何人都有自己独一无二的指纹,这常常成为司法机关鉴别罪犯身份最值得信赖的方法;与之类似,MD5就可以为任何文件(不管其大小、格式、数量)产生一个同样独一无二的MD5“数字指纹”,如果任何人对文件做了任何改动,其MD5也就是对应的“数字指纹”都会发生变化。
❻ ubuntu下链接c语言实现md5出错
你的命令写得有问题:
gcc -o main.o md5.o
-o参数用来指定输出文件名,你这里把main.o传给它了,试试:
gcc -o app main.o md5.o
其实你可以直接一步完成:
gcc md5.c main.c -o main
❼ C语言怎么实现对一长串字符进行MD5加密
#include<stdio.h>
#include<stdlib.h>
#defineARR_LEN100
#defineF(x,y,z)((x&y)|(~x&z))
#defineG(x,y,z)((x&z)|(y&~z))
#defineH(x,y,z)(x^y^z)
#defineI(x,y,z)(y^(x|~z))
#defineROTATE_LEFT(x,n)((x<<n)|(x>>(32-n)))
#defineFF(a,b,c,d,x,s,ac)
{
a+=F(b,c,d)+x+ac;
a=ROTATE_LEFT(a,s);
a+=b;
}
#defineGG(a,b,c,d,x,s,ac)
{
a+=G(b,c,d)+x+ac;
a=ROTATE_LEFT(a,s);
a+=b;
}
#defineHH(a,b,c,d,x,s,ac)
{
a+=H(b,c,d)+x+ac;
a=ROTATE_LEFT(a,s);
a+=b;
}
#defineII(a,b,c,d,x,s,ac)
{
a+=I(b,c,d)+x+ac;
a=ROTATE_LEFT(a,s);
a+=b;
}
typedefstruct{
unsignedintcount[2];
unsignedintstate[4];
unsignedcharbuffer[64];
}MD5_CTX;
voidMD5Init(MD5_CTX*context);
voidMD5Update(MD5_CTX*context,unsignedchar*input,unsignedintinputlen);
voidMD5Final(MD5_CTX*context,unsignedchardigest[16]);
voidMD5Transform(unsignedintstate[4],unsignedcharblock[64]);
voidMD5Encode(unsignedchar*output,unsignedint*input,unsignedintlen);
voidMD5Decode(unsignedint*output,unsignedchar*input,unsignedintlen);
unsignedcharPADDING[]={
0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
voidMD5Init(MD5_CTX*context){
context->count[0]=0;
context->count[1]=0;
context->state[0]=0x67452301;
context->state[1]=0xEFCDAB89;
context->state[2]=0x98BADCFE;
context->state[3]=0x10325476;
}
voidMD5Update(MD5_CTX*context,unsignedchar*input,unsignedintinputlen){
unsignedinti=0,index=0,partlen=0;
index=(context->count[0]>>3)&0x3F;
partlen=64-index;
context->count[0]+=inputlen<<3;
if(context->count[0]<(inputlen<<3))
context->count[1]++;
context->count[1]+=inputlen>>29;
if(inputlen>=partlen){
memcpy(&context->buffer[index],input,partlen);
MD5Transform(context->state,context->buffer);
for(i=partlen;i+64<=inputlen;i+=64)
MD5Transform(context->state,&input[i]);
index=0;
}
else{
i=0;
}
memcpy(&context->buffer[index],&input[i],inputlen-i);
}
voidMD5Final(MD5_CTX*context,unsignedchardigest[16]){
unsignedintindex=0,padlen=0;
unsignedcharbits[8];
index=(context->count[0]>>3)&0x3F;
padlen=(index<56)?(56-index):(120-index);
MD5Encode(bits,context->count,8);
MD5Update(context,PADDING,padlen);
MD5Update(context,bits,8);
MD5Encode(digest,context->state,16);
}
voidMD5Encode(unsignedchar*output,unsignedint*input,unsignedintlen){
unsignedinti=0,j=0;
while(j<len){
output[j]=input[i]&0xFF;
output[j+1]=(input[i]>>8)&0xFF;
output[j+2]=(input[i]>>16)&0xFF;
output[j+3]=(input[i]>>24)&0xFF;
i++;
j+=4;
}
}
voidMD5Decode(unsignedint*output,unsignedchar*input,unsignedintlen){
unsignedinti=0,j=0;
while(j<len){
output[i]=(input[j])|
(input[j+1]<<8)|
(input[j+2]<<16)|
(input[j+3]<<24);
i++;
j+=4;
}
}
voidMD5Transform(unsignedintstate[4],unsignedcharblock[64]){
unsignedinta=state[0];
unsignedintb=state[1];
unsignedintc=state[2];
unsignedintd=state[3];
unsignedintx[64];
MD5Decode(x,block,64);
FF(a,b,c,d,x[0],7,0xd76aa478);/*1*/
FF(d,a,b,c,x[1],12,0xe8c7b756);/*2*/
FF(c,d,a,b,x[2],17,0x242070db);/*3*/
FF(b,c,d,a,x[3],22,0xc1bdceee);/*4*/
FF(a,b,c,d,x[4],7,0xf57c0faf);/*5*/
FF(d,a,b,c,x[5],12,0x4787c62a);/*6*/
FF(c,d,a,b,x[6],17,0xa8304613);/*7*/
FF(b,c,d,a,x[7],22,0xfd469501);/*8*/
FF(a,b,c,d,x[8],7,0x698098d8);/*9*/
FF(d,a,b,c,x[9],12,0x8b44f7af);/*10*/
FF(c,d,a,b,x[10],17,0xffff5bb1);/*11*/
FF(b,c,d,a,x[11],22,0x895cd7be);/*12*/
FF(a,b,c,d,x[12],7,0x6b901122);/*13*/
FF(d,a,b,c,x[13],12,0xfd987193);/*14*/
FF(c,d,a,b,x[14],17,0xa679438e);/*15*/
FF(b,c,d,a,x[15],22,0x49b40821);/*16*/
/*Round2*/
GG(a,b,c,d,x[1],5,0xf61e2562);/*17*/
GG(d,a,b,c,x[6],9,0xc040b340);/*18*/
GG(c,d,a,b,x[11],14,0x265e5a51);/*19*/
GG(b,c,d,a,x[0],20,0xe9b6c7aa);/*20*/
GG(a,b,c,d,x[5],5,0xd62f105d);/*21*/
GG(d,a,b,c,x[10],9,0x2441453);/*22*/
GG(c,d,a,b,x[15],14,0xd8a1e681);/*23*/
GG(b,c,d,a,x[4],20,0xe7d3fbc8);/*24*/
GG(a,b,c,d,x[9],5,0x21e1cde6);/*25*/
GG(d,a,b,c,x[14],9,0xc33707d6);/*26*/
GG(c,d,a,b,x[3],14,0xf4d50d87);/*27*/
GG(b,c,d,a,x[8],20,0x455a14ed);/*28*/
GG(a,b,c,d,x[13],5,0xa9e3e905);/*29*/
GG(d,a,b,c,x[2],9,0xfcefa3f8);/*30*/
GG(c,d,a,b,x[7],14,0x676f02d9);/*31*/
GG(b,c,d,a,x[12],20,0x8d2a4c8a);/*32*/
/*Round3*/
HH(a,b,c,d,x[5],4,0xfffa3942);/*33*/
HH(d,a,b,c,x[8],11,0x8771f681);/*34*/
HH(c,d,a,b,x[11],16,0x6d9d6122);/*35*/
HH(b,c,d,a,x[14],23,0xfde5380c);/*36*/
HH(a,b,c,d,x[1],4,0xa4beea44);/*37*/
HH(d,a,b,c,x[4],11,0x4bdecfa9);/*38*/
HH(c,d,a,b,x[7],16,0xf6bb4b60);/*39*/
HH(b,c,d,a,x[10],23,0xbebfbc70);/*40*/
HH(a,b,c,d,x[13],4,0x289b7ec6);/*41*/
HH(d,a,b,c,x[0],11,0xeaa127fa);/*42*/
HH(c,d,a,b,x[3],16,0xd4ef3085);/*43*/
HH(b,c,d,a,x[6],23,0x4881d05);/*44*/
HH(a,b,c,d,x[9],4,0xd9d4d039);/*45*/
HH(d,a,b,c,x[12],11,0xe6db99e5);/*46*/
HH(c,d,a,b,x[15],16,0x1fa27cf8);/*47*/
HH(b,c,d,a,x[2],23,0xc4ac5665);/*48*/
/*Round4*/
II(a,b,c,d,x[0],6,0xf4292244);/*49*/
II(d,a,b,c,x[7],10,0x432aff97);/*50*/
II(c,d,a,b,x[14],15,0xab9423a7);/*51*/
II(b,c,d,a,x[5],21,0xfc93a039);/*52*/
II(a,b,c,d,x[12],6,0x655b59c3);/*53*/
II(d,a,b,c,x[3],10,0x8f0ccc92);/*54*/
II(c,d,a,b,x[10],15,0xffeff47d);/*55*/
II(b,c,d,a,x[1],21,0x85845dd1);/*56*/
II(a,b,c,d,x[8],6,0x6fa87e4f);/*57*/
II(d,a,b,c,x[15],10,0xfe2ce6e0);/*58*/
II(c,d,a,b,x[6],15,0xa3014314);/*59*/
II(b,c,d,a,x[13],21,0x4e0811a1);/*60*/
II(a,b,c,d,x[4],6,0xf7537e82);/*61*/
II(d,a,b,c,x[11],10,0xbd3af235);/*62*/
II(c,d,a,b,x[2],15,0x2ad7d2bb);/*63*/
II(b,c,d,a,x[9],21,0xeb86d391);/*64*/
state[0]+=a;
state[1]+=b;
state[2]+=c;
state[3]+=d;
}
intmain(intargc,char*argv[]){
inti;
unsignedcharencrypt[ARR_LEN];
unsignedchardecrypt[16];
MD5_CTXmd5;
printf("【测试1】 ");
printf("加密前:Bai ");
printf("加密后: ");
printf(" ");
printf("【测试2】 ");
printf("加密前:Bihaifeng ");
printf("加密后: ");
printf(" ");
printf("====================================================== ");
printf("请输入需MD5加密的字符串: ");
gets(encrypt);
printf(" ");
printf("====================================================== ");
MD5Init(&md5);
MD5Update(&md5,encrypt,strlen((char*)encrypt));
MD5Final(&md5,decrypt);
printf("加密前:%s 加密后:",encrypt);
for(i=0;i<16;i++){
printf("%02x",decrypt[i]);
}
printf(" ");
getch();
return0;
}
运行结果
以上源代码非原创~~
❽ 请教MD5算法 用C语言实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#ifdefined(__APPLE__)
#defineCOMMON_DIGEST_FOR_OPENSSL
#include<CommonCrypto/CommonDigest.h>
#defineSHA1CC_SHA1
#else
#include<openssl/md5.h>
#endif
//这是我自己写的函数,用于计算MD5
//参数str:要转换的字符串
//参数lengthL:字符串的长度可以用strlen(str)直接获取参数str的长度
//返回值:MD5字符串
char*str2md5(constchar*str,intlength){
intn;
MD5_CTXc;
unsignedchardigest[16];
char*out=(char*)malloc(33);
MD5_Init(&c);
while(length>0){
if(length>512){
MD5_Update(&c,str,512);
}else{
MD5_Update(&c,str,length);
}
length-=512;
str+=512;
}
MD5_Final(digest,&c);
for(n=0;n<16;++n){
snprintf(&(out[n*2]),16*2,"%02x",(unsignedint)digest[n]);
}
returnout;
}
intmain(intargc,char**argv){
char*output=str2md5("hello",strlen("hello"));
printf("%s ",output);
//上面会输出hello的MD5字符串:
//
free(output);
return0;
}
❾ 高分求解c语言的简单文件加解密
用C语言实现MD5算法用C语言实现MD5算法,这个够复杂。。。
""用C语言实现MD5算法.
1)global.h 头文件
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
/* PROTO_LIST is defined depending on how PROTOTYPES is defined
above.If using PROTOTYPES, then PROTO_LIST returns the list, otherwise
it returns an empty list. */
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
2)md5.h 头文件
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, molo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
3)md5c.c 算法的核心部分
/* 参考 RSA Data Security, Inc., MD5 message-digest algorithm 的C源程
序
*/
#include "global.h"
#include "md5.h"
/* MD5的主循环的轮主要操作为a=b+((a+f(b,c,d)+M+t)<<值如下:
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
/*函数调用说明*/
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned
int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I 是MD5的基本函数.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT将 x 循环左移n bits. */
#define ROTATE_LEFT(x, n) (((x) <> (32-(n))))
/* FF, GG, HH, and II 代表1,2,3,4轮计算,先宏定义以便于后面引用.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 的初始化, MD5 操作的开始. */
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* 给出4个32比特的初始向量.*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 块更新操作.不断地对消息块进行MD5 消息-摘要操作,并更新
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 state, &input);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input,
inputLen-i);
}
/* MD5 的结束操作. 输出128比特的散列值并对context归零.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /*
context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* 对一个消息块的16个子块进行MD5 基本计算.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4. */
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{ unsigned int i, j;
for (i = 0, j = 0; j > 8) & 0xff);
output[j+2] = (unsigned char)((input >> 16) & 0xff);
output[j+3] = (unsigned char)((input >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is a
multiple of 4. */
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible. */
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{ unsigned int i;
for (i = 0; i < len; i++)
output = input;
}
/* Note: Replace "for loop" with standard memset if possible. */
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{ unsigned int i;
for (i = 0; i < len; i++)
((char *)output) = (char)value;
}
4)md5test.c 主测试程序
/* MD5测试程序 */
#include
#include
#include "global.h"
#include "md5.h"
/* Length of test block, number of test blocks. */
static void MDString PROTO_LIST ((char *));
static void MDFilter PROTO_LIST ((void));
static void MDPrint PROTO_LIST ((unsigned char [16]));
/* Prints a message digest in hexadecimal.(十六进制) */
static void MDPrint (digest)
unsigned char digest[16];
{
unsigned int i;
printf("\n");
for (i = 0; i < 16; i++)
printf ("%02x", digest);
}
/* Digests the standard input and prints the result. */
static void MDFilter ()
{
MD5_CTX context;
int len;
unsigned char buffer[16], digest[16];
MD5Init (&context);
while (len = fread (buffer, 1, 16, stdin))
MD5Update (&context, buffer, len);
MD5Final (digest, &context);
MDPrint (digest);
printf ("\n");
}
/* Digests a string and prints the result. */
static void MDString (string)
char *string;
{
MD5_CTX context;
unsigned char digest[16];
unsigned int len = strlen (string);
MD5Init (&context);
MD5Update (&context, string, len);
MD5Final (digest, &context);
printf ("%s = ", string);
MDPrint (digest);
printf ("\n");
}
void main ()
{
printf ("MD5算法测试:\n");
printf ("原文=\n");
printf ("MD5消息摘要\n");
MDString ("\n赵涛");
MDString ("\n合肥电大站 学号:01230100015");
MDString
("\
123456789");
}
❿ 求一个简单的md5加密程序C或C++代码
C语言实现MD5算法
#include<stdio.h>
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define RL(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) //x向左循环移y位
#define PP(x) (x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24) //将x高低位互换,例如PP(aabbccdd)=ddccbbaa
#define FF(a, b, c, d, x, s, ac) a = b + (RL((a + F(b,c,d) + x + ac),s))
#define GG(a, b, c, d, x, s, ac) a = b + (RL((a + G(b,c,d) + x + ac),s))
#define HH(a, b, c, d, x, s, ac) a = b + (RL((a + H(b,c,d) + x + ac),s))
#define II(a, b, c, d, x, s, ac) a = b + (RL((a + I(b,c,d) + x + ac),s))
unsigned A,B,C,D,a,b,c,d,i,len,flen[2],x[16]; //i临时变量,len文件长,flen[2]为64位二进制表示的文件初始长度
char filename[200]; //文件名
FILE *fp;
void md5(){ //MD5核心算法,供64轮
a=A,b=B,c=C,d=D;
/**//* Round 1 */
FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /**//* 1 */
FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /**//* 2 */
FF (c, d, a, b, x[ 2], 17, 0x242070db); /**//* 3 */
FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /**//* 4 */
FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /**//* 5 */
FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /**//* 6 */
FF (c, d, a, b, x[ 6], 17, 0xa8304613); /**//* 7 */
FF (b, c, d, a, x[ 7], 22, 0xfd469501); /**//* 8 */
FF (a, b, c, d, x[ 8], 7, 0x698098d8); /**//* 9 */
FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /**//* 10 */
FF (c, d, a, b, x[10], 17, 0xffff5bb1); /**//* 11 */
FF (b, c, d, a, x[11], 22, 0x895cd7be); /**//* 12 */
FF (a, b, c, d, x[12], 7, 0x6b901122); /**//* 13 */
FF (d, a, b, c, x[13], 12, 0xfd987193); /**//* 14 */
FF (c, d, a, b, x[14], 17, 0xa679438e); /**//* 15 */
FF (b, c, d, a, x[15], 22, 0x49b40821); /**//* 16 */
/**//* Round 2 */
GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /**//* 17 */
GG (d, a, b, c, x[ 6], 9, 0xc040b340); /**//* 18 */
GG (c, d, a, b, x[11], 14, 0x265e5a51); /**//* 19 */
GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /**//* 20 */
GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /**//* 21 */
GG (d, a, b, c, x[10], 9, 0x02441453); /**//* 22 */
GG (c, d, a, b, x[15], 14, 0xd8a1e681); /**//* 23 */
GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /**//* 24 */
GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /**//* 25 */
GG (d, a, b, c, x[14], 9, 0xc33707d6); /**//* 26 */
GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /**//* 27 */
GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /**//* 28 */
GG (a, b, c, d, x[13], 5, 0xa9e3e905); /**//* 29 */
GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /**//* 30 */
GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /**//* 31 */
GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /**//* 32 */
/**//* Round 3 */
HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /**//* 33 */
HH (d, a, b, c, x[ 8], 11, 0x8771f681); /**//* 34 */
HH (c, d, a, b, x[11], 16, 0x6d9d6122); /**//* 35 */
HH (b, c, d, a, x[14], 23, 0xfde5380c); /**//* 36 */
HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /**//* 37 */
HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /**//* 38 */
HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /**//* 39 */
HH (b, c, d, a, x[10], 23, 0xbebfbc70); /**//* 40 */
HH (a, b, c, d, x[13], 4, 0x289b7ec6); /**//* 41 */
HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /**//* 42 */
HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /**//* 43 */
HH (b, c, d, a, x[ 6], 23, 0x04881d05); /**//* 44 */
HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /**//* 45 */
HH (d, a, b, c, x[12], 11, 0xe6db99e5); /**//* 46 */
HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /**//* 47 */
HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /**//* 48 */
/**//* Round 4 */
II (a, b, c, d, x[ 0], 6, 0xf4292244); /**//* 49 */
II (d, a, b, c, x[ 7], 10, 0x432aff97); /**//* 50 */
II (c, d, a, b, x[14], 15, 0xab9423a7); /**//* 51 */
II (b, c, d, a, x[ 5], 21, 0xfc93a039); /**//* 52 */
II (a, b, c, d, x[12], 6, 0x655b59c3); /**//* 53 */
II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /**//* 54 */
II (c, d, a, b, x[10], 15, 0xffeff47d); /**//* 55 */
II (b, c, d, a, x[ 1], 21, 0x85845dd1); /**//* 56 */
II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /**//* 57 */
II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /**//* 58 */
II (c, d, a, b, x[ 6], 15, 0xa3014314); /**//* 59 */
II (b, c, d, a, x[13], 21, 0x4e0811a1); /**//* 60 */
II (a, b, c, d, x[ 4], 6, 0xf7537e82); /**//* 61 */
II (d, a, b, c, x[11], 10, 0xbd3af235); /**//* 62 */
II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /**//* 63 */
II (b, c, d, a, x[ 9], 21, 0xeb86d391); /**//* 64 */
A += a;
B += b;
C += c;
D += d;
}
main(){
while(1){
printf("Input file:");
gets(filename); //用get函数,避免scanf以空格分割数据,
if (filename[0]==34) filename[strlen(filename)-1]=0,strcpy(filename,filename+1); //支持文件拖曳,但会多出双引号,这里是处理多余的双引号
if (!strcmp(filename,"exit")) exit(0); //输入exit退出
if (!(fp=fopen(filename,"rb"))) {printf("Can not open this file!\n");continue;} //以二进制打开文件
fseek(fp, 0, SEEK_END); //文件指针转到文件末尾
if((len=ftell(fp))==-1) {printf("Sorry! Can not calculate files which larger than 2 GB!\n");fclose(fp);continue;} //ftell函数返回long,最大为2GB,超出返回-1
rewind(fp); //文件指针复位到文件头
A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476; //初始化链接变量
flen[1]=len/0x20000000; //flen单位是bit
flen[0]=(len%0x20000000)*8;
memset(x,0,64); //初始化x数组为0
fread(&x,4,16,fp); //以4字节为一组,读取16组数据
for(i=0;i<len/64;i++){ //循环运算直至文件结束
md5();
memset(x,0,64);
fread(&x,4,16,fp);
}
((char*)x)[len%64]=128; //文件结束补1,补0操作,128二进制即10000000
if(len%64>55) md5(),memset(x,0,64);
memcpy(x+14,flen,8); //文件末尾加入原文件的bit长度
md5();
fclose(fp);
printf("MD5 Code:%08x%08x%08x%08x\n",PP(A),PP(B),PP(C),PP(D)); //高低位逆反输出
}
}