sinat_24243075 2015-07-15 07:35 采纳率: 50%
浏览 1889

关于MD5算法(C版)!我自己写的!超过2G校验失败

考虑到平台的兼容性,所以代码有点冗长,刚完成,2G以上的文件无法校验,所以,性能也没有优化,代码也没有整理,求大神指点迷津,为什么检验2G以上的文件会出错?

 #include<stdio.h>
#include<string.h>
#include<malloc.h>
#ifdef _WIN32
#include<windows.h>
#endif


//the program can't get right result;
//MD5.h
#ifdef uint64
#undef uint64
#define uint64 unsigned long long
#else
#define uint64 unsigned long long
#endif

#ifdef uint32
#undef uint32
#define uint32 unsigned int
#else
#define uint32 unsigned int
#endif

#ifdef uchar
#undef uchar
#define uchar unsigned char
#else
#define uchar unsigned char
#endif
//when you write a Macro,you should be care for bracket,because of Operation sequence
#ifdef crol
#undef crol
#define crol(temp,s) ((temp<<s)|(temp>>(0x20-s)))
#else
#define crol(temp,s) ((temp<<s)|(temp>>(0x20-s)))
#endif

#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 FF(a,b,c,d,Mj,s,ti) a=b+(crol((a+F(b,c,d)+Mj+ti),s))
#define GG(a,b,c,d,Mj,s,ti) a=b+(crol((a+G(b,c,d)+Mj+ti),s))
#define HH(a,b,c,d,Mj,s,ti) a=b+(crol((a+H(b,c,d)+Mj+ti),s))
#define II(a,b,c,d,Mj,s,ti) a=b+(crol((a+I(b,c,d)+Mj+ti),s))

#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476


#define BIT 8
#define BLOCK_SIZE 512
#define MOD_SIZE_BT 448
#define MOD_SIZE_BY MOD_SIZE_BT/BIT
#define FIRST_APPEND_BYTE 0x80
#define FILE_LEN 8
#define BLOCK_BYTE 64

typedef struct File_Info
{
    bool Get_Len;
    FILE *File_Point;
    uint64 Info_Len, Info_Mod, Info_Size, Info_Div;
}FILE_POINT, *PFILE_POINT;

FILE_POINT File_S;

uint32 State[4] = { 0 };

uchar Ciphertext_32[16];


inline void Init_Info();
void MD5(char *Msg);
bool Init(char *Msg, char Type);
uint32 *Block_Sort(char *Info);
void GetMd5(char *Info, char);
uint64 Get_File_Len_Linux_Windows(char *filename);
#ifdef _WIN32
LPCTSTR Multi_To_Wide(char * Old_Name);
#endif
//MD5.c

#ifdef _WIN32
LPCTSTR Multi_To_Wide(char * Old_Name)
{
    int num = MultiByteToWideChar(0, 0, Old_Name, -1, NULL, 0);
    LPTSTR Now_Name = (LPTSTR)malloc(sizeof(wchar_t)*num);
    MultiByteToWideChar(0, 0, Old_Name, -1, Now_Name, num);
    return Now_Name;
}
#endif
uint64 Get_File_Len_Linux_Windows(char *filename)
{
#ifdef __linux
    int i;
    struct stat statbuf;
    if ((i = stat(Msg, &statbuf)) == 0)
    {
        File_S.Get_Len = true;
        return statbuf.st_size;
    }
    else{
        File_S.Get_Len = false;
    }
#endif
#ifdef _WIN32
    uint64 File_Len = 0x0;
    LPCTSTR Win_filename;
    DWORD High, Low;
    WIN32_FIND_DATA wfd = { 0 };
    Win_filename = Multi_To_Wide(filename);
    HANDLE hFile = FindFirstFile(Win_filename, &wfd);
    if (hFile != NULL)
    {
        Low = wfd.nFileSizeLow;
        High = wfd.nFileSizeHigh;
        File_Len = Low | ((File_Len = High) << 32);
        File_S.Get_Len = true;
    }
    else File_S.Get_Len = false;
        FindClose(hFile);
    return File_Len;
#endif
}
inline void Init_Info()
{
    File_S.Info_Div = (File_S.Info_Len*BIT) / BLOCK_SIZE;
    File_S.Info_Mod = (File_S.Info_Len*BIT) % BLOCK_SIZE;
    File_S.Info_Size = File_S.Info_Len*BIT;
}
bool Init(char *Msg, char Type)
{
    State[0] = A;
    State[1] = B;
    State[2] = C;
    State[3] = D;
    if (Type == 'M')
    {
        File_S.File_Point = NULL;
        File_S.Info_Len = strlen(Msg);
        Init_Info();
        return true;
    }
    else if (Type == 'F')
    {
        File_S.File_Point = fopen(Msg, "rb");
        File_S.Info_Len = Get_File_Len_Linux_Windows(Msg);
        if (File_S.Get_Len == false) return false;
        Init_Info();
        return true;
    }
    else
        return false;
}
uint32 *Block_Sort(char *Info)
{
    static uint32 Num[16] = { 0 };
    int i;
    for (i = 0; i<16; i++)
    {
        memmove(&Num[i], &Info[i * 4], 4);
    }
    return Num;
}
void MD5(char *Msg)//只需要传入512位
{
    uint32 *M, a, b, c, d;
    M = Block_Sort(Msg);
    a = State[0];
    b = State[1];
    c = State[2];
    d = State[3];
    FF(a, b, c, d, M[0], 7, 0xd76aa478);
    FF(d, a, b, c, M[1], 12, 0xe8c7b756);
    FF(c, d, a, b, M[2], 17, 0x242070db);
    FF(b, c, d, a, M[3], 22, 0xc1bdceee);
    FF(a, b, c, d, M[4], 7, 0xf57c0faf);
    FF(d, a, b, c, M[5], 12, 0x4787c62a);
    FF(c, d, a, b, M[6], 17, 0xa8304613);
    FF(b, c, d, a, M[7], 22, 0xfd469501);
    FF(a, b, c, d, M[8], 7, 0x698098d8);
    FF(d, a, b, c, M[9], 12, 0x8b44f7af);
    FF(c, d, a, b, M[10], 17, 0xffff5bb1);
    FF(b, c, d, a, M[11], 22, 0x895cd7be);
    FF(a, b, c, d, M[12], 7, 0x6b901122);
    FF(d, a, b, c, M[13], 12, 0xfd987193);
    FF(c, d, a, b, M[14], 17, 0xa679438e);
    FF(b, c, d, a, M[15], 22, 0x49b40821);


    GG(a, b, c, d, M[1], 5, 0xf61e2562);
    GG(d, a, b, c, M[6], 9, 0xc040b340);
    GG(c, d, a, b, M[11], 14, 0x265e5a51);
    GG(b, c, d, a, M[0], 20, 0xe9b6c7aa);
    GG(a, b, c, d, M[5], 5, 0xd62f105d);
    GG(d, a, b, c, M[10], 9, 0x2441453);
    GG(c, d, a, b, M[15], 14, 0xd8a1e681);
    GG(b, c, d, a, M[4], 20, 0xe7d3fbc8);
    GG(a, b, c, d, M[9], 5, 0x21e1cde6);
    GG(d, a, b, c, M[14], 9, 0xc33707d6);
    GG(c, d, a, b, M[3], 14, 0xf4d50d87);
    GG(b, c, d, a, M[8], 20, 0x455a14ed);
    GG(a, b, c, d, M[13], 5, 0xa9e3e905);
    GG(d, a, b, c, M[2], 9, 0xfcefa3f8);
    GG(c, d, a, b, M[7], 14, 0x676f02d9);
    GG(b, c, d, a, M[12], 20, 0x8d2a4c8a);


    HH(a, b, c, d, M[5], 4, 0xfffa3942);
    HH(d, a, b, c, M[8], 11, 0x8771f681);
    HH(c, d, a, b, M[11], 16, 0x6d9d6122);
    HH(b, c, d, a, M[14], 23, 0xfde5380c);
    HH(a, b, c, d, M[1], 4, 0xa4beea44);
    HH(d, a, b, c, M[4], 11, 0x4bdecfa9);
    HH(c, d, a, b, M[7], 16, 0xf6bb4b60);
    HH(b, c, d, a, M[10], 23, 0xbebfbc70);
    HH(a, b, c, d, M[13], 4, 0x289b7ec6);
    HH(d, a, b, c, M[0], 11, 0xeaa127fa);
    HH(c, d, a, b, M[3], 16, 0xd4ef3085);
    HH(b, c, d, a, M[6], 23, 0x4881d05);
    HH(a, b, c, d, M[9], 4, 0xd9d4d039);
    HH(d, a, b, c, M[12], 11, 0xe6db99e5);
    HH(c, d, a, b, M[15], 16, 0x1fa27cf8);
    HH(b, c, d, a, M[2], 23, 0xc4ac5665);


    II(a, b, c, d, M[0], 6, 0xf4292244);
    II(d, a, b, c, M[7], 10, 0x432aff97);
    II(c, d, a, b, M[14], 15, 0xab9423a7);
    II(b, c, d, a, M[5], 21, 0xfc93a039);
    II(a, b, c, d, M[12], 6, 0x655b59c3);
    II(d, a, b, c, M[3], 10, 0x8f0ccc92);
    II(c, d, a, b, M[10], 15, 0xffeff47d);
    II(b, c, d, a, M[1], 21, 0x85845dd1);
    II(a, b, c, d, M[8], 6, 0x6fa87e4f);
    II(d, a, b, c, M[15], 10, 0xfe2ce6e0);
    II(c, d, a, b, M[6], 15, 0xa3014314);
    II(b, c, d, a, M[13], 21, 0x4e0811a1);
    II(a, b, c, d, M[4], 6, 0xf7537e82);
    II(d, a, b, c, M[11], 10, 0xbd3af235);
    II(c, d, a, b, M[2], 15, 0x2ad7d2bb);
    II(b, c, d, a, M[9], 21, 0xeb86d391);
    State[0] += a;
    State[1] += b;
    State[2] += c;
    State[3] += d;
}
void GetMd5(char *Info, char Type = 'M')//
{
    int i;
    char *Data_Temp = (char*)malloc(BLOCK_BYTE);
    char *Temp = (char*)malloc(BLOCK_BYTE);
    if (Init(Info, Type))
    {
        for (i = 0; i <= File_S.Info_Div + 1; i++)
        {
            memset(Data_Temp, 0x0, BLOCK_BYTE);
            memset(Temp, 0x0, BLOCK_BYTE);
            if (Type == 'F')
            {
                fread(Temp, 4, 16, File_S.File_Point);
            }
            else{
                strncpy(Temp, &Info[i*BLOCK_BYTE], File_S.Info_Len);//strncpy,memmove,src不够长直接接着地址往下读,但是memmove全部读,strncpy,读指定字节只读0x0之前的
            }
            if (File_S.Info_Mod<448){
                if (i == File_S.Info_Div)
                {
                    memmove(Data_Temp, Temp, BLOCK_BYTE);
                    memmove(&Data_Temp[BLOCK_BYTE - FILE_LEN], &File_S.Info_Size, FILE_LEN);
                    Data_Temp[File_S.Info_Mod / BIT] = FIRST_APPEND_BYTE;
                    goto Do_5;
                }
                if (i == File_S.Info_Div + 1) goto End;
            }
            else{
                if (i == File_S.Info_Div + 1)
                {
                    memmove(&Data_Temp[BLOCK_BYTE - FILE_LEN], &File_S.Info_Size, FILE_LEN);
                    goto Do_5;
                }
                else if (i == File_S.Info_Div)
                {
                    memmove(Data_Temp, Temp, BLOCK_BYTE);
                    Data_Temp[File_S.Info_Mod / BIT] = FIRST_APPEND_BYTE;
                    goto Do_5;
                }
            }
            memmove(Data_Temp, Temp, BLOCK_BYTE);
        Do_5:       MD5(Data_Temp);
        End:;
        }
    }
    free(Data_Temp);
    free(Temp);
}
int main()//文件太大时,时间长且结果错误,需优化算法<2G左右计算OK
{
    char *p = "E:\\Test_.exe";
    GetMd5(p, 'F');//完全版,p可以是字符串,也可以是文件名,main函数自己写,F代表file,M代表字符串
    int i;
    for (i = 0; i<16; i++)
    {
        Ciphertext_32[i] = (State[i / 4] >> (i % 4) * 8) & 0xff;
    }
    printf("32BIT:");
    for (i = 0; i < 16; i++)
    {
        printf("%02x", Ciphertext_32[i]);
    }
    printf("\n16BIT:");
    for (i = 4; i < 12; i++)
    {
        printf("%02x", Ciphertext_32[i]);
    }
    getchar();
}
  • 写回答

1条回答 默认 最新

  • oyljerry 2015-07-16 13:31
    关注

    出错是代码返回错误还是结果不对,代码返回错误,是不是文件读取失败了,或者内存没有i及时释放,2G导致内存不够,要具体分析。

    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能