[代码实例][C语言]MD5算法

来源:互联网 发布:node excelexport 编辑:程序博客网 时间:2024/06/05 04:31

此算法存在一些问题,需要与http://blog.csdn.net/cloudblaze/article/details/51749513一致。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define BITS_PER_BYTE   8#define GROUP_BITS      512#define GROUP_SIZE      (GROUP_BITS / BITS_PER_BYTE)    // 64#define SUBGROUPS_PER_GROUP 16#define SUBGROUP_BITS       (GROUP_BITS / SUBGROUPS_PER_GROUP)  // 32#define SUBGROUP_SIZE       (GROUP_SIZE / SUBGROUPS_PER_GROUP)  // 4#define VAR_INPUT_LEN_SIZE  8#define ROL(val,n)  (((val) << (n)) | ((val) >> (32 - (n))))#define ABS(x)      ((x) >= 0 ? (x) : -(x))#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))))unsigned int state[] = {    0x67452301,    0xEFCDAB89,    0x98BADCFE,    0x10325476};unsigned int ti[64];unsigned int round_index[64];const unsigned int s[][4] = {    {7, 12, 17, 22}, {7, 12, 17, 22}, {7, 12, 17, 22}, {7, 12, 17, 22},     {5, 9, 14, 20}, {5, 9, 14, 20}, {5, 9, 14, 20}, {5, 9, 14, 20},     {4, 11, 16, 23}, {4, 11, 16, 23}, {4, 11, 16, 23}, {4, 11, 16, 23},     {6, 10, 15, 21}, {6, 10, 15, 21}, {6, 10, 15, 21}, {6, 10, 15, 21}};size_t add_bits(const char * src, unsigned char ** p_dest);void transform(unsigned char sub_group[SUBGROUPS_PER_GROUP][SUBGROUP_SIZE]);char * md5(const unsigned char * mem, char * buf);int main(int argc, char * argv[]){    const unsigned char * mem = NULL;    char buf[33] = {0};    if(argc > 2)    {        printf("Usage: %s <string>\n", argv[0]);        return EXIT_SUCCESS;    }    if(argc == 1)        mem = "";    else        mem = argv[1];    printf("%s\n", md5(mem, buf));    return EXIT_SUCCESS;}char * md5(const unsigned char * mem, char * buf){    unsigned char * dest;    unsigned char * group_start;    size_t dest_len;    unsigned char sub_group[SUBGROUPS_PER_GROUP][SUBGROUP_SIZE];    for(int i = 0; i < 64; i++)        ti[i] = (1UL << 32) * ABS(sin(i + 1));    dest_len = add_bits(mem, &dest);    group_start = dest;    for(int i = 0;        i < dest_len / GROUP_SIZE;        i++, group_start += GROUP_SIZE)    {        memcpy((unsigned char *)sub_group, group_start, GROUP_SIZE);        transform(sub_group);    }    unsigned char * pstate = (unsigned char *)state;    char * pbuf = buf;    for(int i = 0; i < 16; i++)    {        snprintf(pbuf, 3, "%02X", *pstate);        pbuf += 2;        pstate++;    }    free(dest);    return buf;}/* * add_bits: 将输入补充二进制位。补充二进制位时,首先使其位长度len满足 *      len % 512bits = 448bits(56bytes)。填充时,首先填充一位1,剩余的 *      位均填充0。然后,再填充64bits(8bytes),其值为未填充前的二进制位长 *      度。 * in@src: 原始输入。 * out@p_dest: 指向填充后的内存空间的指针的指针。 * return: 填充后的内存空间大小。 */size_t add_bits(const char * src, unsigned char ** p_dest){    size_t src_len;    size_t dest_len;    size_t rest_len;    unsigned char * dest;    src_len = strlen(src);    if(src_len == 0)        dest_len = GROUP_SIZE;    else        dest_len = (src_len + GROUP_SIZE - 1) / GROUP_SIZE * GROUP_SIZE;    rest_len = GROUP_SIZE - src_len % GROUP_SIZE;    if(rest_len < VAR_INPUT_LEN_SIZE)        dest_len += GROUP_SIZE;    if((dest = malloc(dest_len)) == NULL)    {        perror("malloc");        exit(EXIT_FAILURE);    }    memset(dest, 0, dest_len);    strncpy(dest, src, src_len);    if(rest_len > VAR_INPUT_LEN_SIZE)    {        dest[src_len] = 0x80;        memset(dest + src_len + 1, 0, rest_len - 1 - VAR_INPUT_LEN_SIZE);    }    else if(rest_len < VAR_INPUT_LEN_SIZE)    {        dest[src_len] = 0x80;        memset(dest + src_len + 1, 0, rest_len - 1 + GROUP_SIZE - VAR_INPUT_LEN_SIZE);    }    *(unsigned long long *)(dest + dest_len - VAR_INPUT_LEN_SIZE) = (unsigned long long)src_len * BITS_PER_BYTE;    *p_dest = dest;    return dest_len;}/* * transform: 转换分组 */void transform(unsigned char sub_group[SUBGROUPS_PER_GROUP][SUBGROUP_SIZE]){    unsigned int a;    unsigned int b;    unsigned int c;    unsigned int d;    unsigned int tmp;    unsigned int result, index;    a = state[0];    b = state[1];    c = state[2];    d = state[3];    for(int i = 0; i < 64; i++)    {        if(i < 16)        {            result = F(b, c, d);            index = i;        }        else if(i < 32)        {            result = G(b, c, d);            index = (5 * i + 1) % 16;        }        else if(i < 48)        {            result = H(b, c, d);            index = (3 * i + 5) % 16;        }        else        {            result = I(b, c, d);            index = (7 * i) % 16;        }        tmp = d;        d = c;        c = b;        b = b + ROL(                    a + result + *(unsigned int *)&sub_group[index] + ti[i],                    *((const unsigned int *)s + i));        a = tmp;    }    state[0] += a;    state[1] += b;    state[2] += c;    state[3] += d;}
0 0