130行代码C语言实现的MD5计算器,用于嵌入式系统

//stack size 00x100 is not avalible for this ddl
#include "math.h"
#include "string.h"

unsigned long Nonlinear_Func(unsigned long x,unsigned long y,unsigned long z,unsigned char Func_Type){
    if (Func_Type==0x46){//F_FUNC
        return((x&y)|((~x)&z));
    }
    else if (Func_Type==0x47){//G_FUNC
        return((x&z)|(y&(~z)));
    }
    else if (Func_Type==0x48){//H_FUNC
        return(x^y^z);
    }
    else if (Func_Type==0x49){//I_FUNC
        return(y^(x|(~z)));
    }
    else {
        return 0;
    }
}


unsigned long Cycle_Left_Move_Bit(unsigned long Number,unsigned char Bits_Moved){

    unsigned char temp,Hi_Bit;
    unsigned long tempp=Number;
    for (temp=0;temp<Bits_Moved;temp++){
        Hi_Bit=tempp>>31;
        tempp=(tempp<<1)+Hi_Bit;
    }
    return tempp;
}

void One_MD5_OP(\
unsigned long* num1,\
unsigned long* num2,\
unsigned long* num3,\
unsigned long* num4,\
unsigned long Son_Group,\
unsigned char Bits_Moved,\
unsigned long Constant_Number,\
unsigned char Nonlinear_Func_Type\
){
    *num1 = *num2 + Cycle_Left_Move_Bit((*num1+Nonlinear_Func(*num2,*num3,*num4,Nonlinear_Func_Type)+Son_Group+Constant_Number),Bits_Moved);
}

void Calculate_Data_MD5_Number(\
unsigned long* Result_Group,\
unsigned long Start_Address,\
unsigned long long Data_Length_Byte\
){
    unsigned long A=0x67452301,B=0xEFCDAB89,C=0x98BADCFE,D=0x10325476,a=A,b=B,c=C,d=D,MD5_Group[16];
    unsigned char Son_Group_Pointer=0,temp=0,tempp;
    unsigned long long Group_Pointer=0;
    const unsigned char  Son_Group_Flag[64]={\
        0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\
        1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,\
        5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,\
        0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9\
    };
    const unsigned char  Bits_Moved_Number[16]={\
        7,12,17,22,\
        5,9,14,20,\
        4,11,16,23,\
        6,10,15,21,\
    };
    

    if ((Data_Length_Byte+9)%64==0){
        tempp=(Data_Length_Byte+9)/64-1;
    }
    else{
        tempp=(Data_Length_Byte+9)/64;
    }
    
    for (Group_Pointer=0;Group_Pointer<=tempp;Group_Pointer++){//大组共n组,一组64字节
        
        memset(MD5_Group,0,64);

        for (Son_Group_Pointer=0;Son_Group_Pointer<16;Son_Group_Pointer++){//小组共16组,一组4字节

            for (temp=0;temp<4;temp++){//1个小组由4字节组成
                    
                if ((Group_Pointer*64+Son_Group_Pointer*4+temp)==Data_Length_Byte){//读取指针是否越界且指向边界外第一个字节
									
                    MD5_Group[Son_Group_Pointer]|=0x80<<(8*(temp));
                }
                
                if ((Group_Pointer==tempp)&&((Group_Pointer*64+Son_Group_Pointer*4+temp)>=Data_Length_Byte)){//读取指针越界&&是最后一大组
                    MD5_Group[14]=Data_Length_Byte*8;//最后两个小组填充为待校验数据大小
                    MD5_Group[15]=(Data_Length_Byte*8)>>32;
                    goto Operation;
                }
                else if ((Group_Pointer*64+Son_Group_Pointer*4+temp)==Data_Length_Byte){//读取指针越界&&并不是最后一大组
                    goto Operation;
                }

                MD5_Group[Son_Group_Pointer]|=((*((volatile unsigned char*)(Start_Address+Group_Pointer*64+Son_Group_Pointer*4+temp)))<<(8*temp));//从地址中读取数据

            }
        }

        Operation:

        for (temp=0;temp<16;temp++){//4次操作循环16次,共64次操作
            One_MD5_OP(&a,&b,&c,&d,MD5_Group[Son_Group_Flag[temp*4]],Bits_Moved_Number[((temp*4/16)*4)+((temp*4)%4)],floor(pow(2,32)*fabs(sin(temp*4+1))),(temp/4+0x46));
            One_MD5_OP(&d,&a,&b,&c,MD5_Group[Son_Group_Flag[temp*4+1]],Bits_Moved_Number[(((temp*4+1)/16)*4)+((temp*4+1)%4)],floor(pow(2,32)*fabs(sin(temp*4+2))),(temp/4+0x46));
            One_MD5_OP(&c,&d,&a,&b,MD5_Group[Son_Group_Flag[temp*4+2]],Bits_Moved_Number[(((temp*4+2)/16)*4)+((temp*4+2)%4)],floor(pow(2,32)*fabs(sin(temp*4+3))),(temp/4+0x46));
            One_MD5_OP(&b,&c,&d,&a,MD5_Group[Son_Group_Flag[temp*4+3]],Bits_Moved_Number[(((temp*4+3)/16)*4)+((temp*4+3)%4)],floor(pow(2,32)*fabs(sin(temp*4+4))),(temp/4+0x46));
        }

        a+=A;
        b+=B;
        c+=C;
        d+=D;
        
        A=a;
        B=b;
        C=c;
        D=d;

    }

    Result_Group[0]=((a<<24)|((a<<8)&0x00ff0000)|((a>>8)&0x0000ff00)|(a>>24));
    Result_Group[1]=((b<<24)|((b<<8)&0x00ff0000)|((b>>8)&0x0000ff00)|(b>>24));
    Result_Group[2]=((c<<24)|((c<<8)&0x00ff0000)|((c>>8)&0x0000ff00)|(c>>24));
    Result_Group[3]=((d<<24)|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|(d>>24));

    return;
}


代码仅供参考,有基本测试过,使用keil编译器的microlib+三级代码优化,编译后大小约为3KB,实际使用请严格测试。如有bug欢迎指出,有空就改(笑)。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值