码迷,mamicode.com
首页 > 其他好文 > 详细

练习 md5sum

时间:2015-09-27 06:41:04      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define rol(x, n) ( ((x) << (n)) | ((x) >> (32-(n))) )

#define FF(b, c, d) (d ^ (b & (c ^ d)))
#define FG(b, c, d) FF (d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))

uint32_t cvt32(uint32_t i)
{
    union {
        uint32_t u;
        uint8_t c[4];
    } a, b;
    b.u = i;

    int n = 4;
    while(n--)
        a.c[n] = b.c[3-n];

    return a.u;
}

uint64_t cvt64(uint64_t i)
{
    union {
        uint64_t u;
        uint8_t c[8];
    } a, b;
    b.u = i;

    int n = 8;
    while(n--)
        a.c[n] = b.c[7-n];

    return a.u;
}

int is_big_endian;

void judge_endian()
{
    union {
        int i;
        char c;
    } u;

    u.i = 1;
    is_big_endian = (u.c == 0);
}

void md5_calc(uint32_t abcd[4], uint32_t data[16])
{
    uint32_t correct_words[16];

    int i;

    if(is_big_endian) {
        for(i = 0; i < 16; i++)
            correct_words[i] = cvt32(data[i]);
    } else {
        memcpy(correct_words, data, 64);
    }

    uint32_t * cwp = correct_words;

    uint32_t A = abcd[0];
    uint32_t B = abcd[1];
    uint32_t C = abcd[2];
    uint32_t D = abcd[3];

#define OP(a, b, c, d, s, T) do {          a += FF (b, c, d) + (*cwp++) + T;      a = rol(a, s);                         a += b;                            } while (0)

    /* Round 1.  */
    OP (A, B, C, D,  7, 0xd76aa478);
    OP (D, A, B, C, 12, 0xe8c7b756);
    OP (C, D, A, B, 17, 0x242070db);
    OP (B, C, D, A, 22, 0xc1bdceee);
    OP (A, B, C, D,  7, 0xf57c0faf);
    OP (D, A, B, C, 12, 0x4787c62a);
    OP (C, D, A, B, 17, 0xa8304613);
    OP (B, C, D, A, 22, 0xfd469501);
    OP (A, B, C, D,  7, 0x698098d8);
    OP (D, A, B, C, 12, 0x8b44f7af);
    OP (C, D, A, B, 17, 0xffff5bb1);
    OP (B, C, D, A, 22, 0x895cd7be);
    OP (A, B, C, D,  7, 0x6b901122);
    OP (D, A, B, C, 12, 0xfd987193);
    OP (C, D, A, B, 17, 0xa679438e);
    OP (B, C, D, A, 22, 0x49b40821);

#undef OP
#define OP(f, a, b, c, d, k, s, T) do {            a += f (b, c, d) + correct_words[k] + T;       a = rol(a, s);                                 a += b;                                    } while (0)

    /* Round 2.  */
    OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
    OP (FG, D, A, B, C,  6,  9, 0xc040b340);
    OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
    OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
    OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
    OP (FG, D, A, B, C, 10,  9, 0x02441453);
    OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
    OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
    OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
    OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
    OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
    OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
    OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
    OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
    OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
    OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);

    /* Round 3.  */
    OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
    OP (FH, D, A, B, C,  8, 11, 0x8771f681);
    OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
    OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
    OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
    OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
    OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
    OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
    OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
    OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
    OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
    OP (FH, B, C, D, A,  6, 23, 0x04881d05);
    OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
    OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
    OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
    OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);

    /* Round 4.  */
    OP (FI, A, B, C, D,  0,  6, 0xf4292244);
    OP (FI, D, A, B, C,  7, 10, 0x432aff97);
    OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
    OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
    OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
    OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
    OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
    OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
    OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
    OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
    OP (FI, C, D, A, B,  6, 15, 0xa3014314);
    OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
    OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
    OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
    OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
    OP (FI, B, C, D, A,  9, 21, 0xeb86d391);

    abcd[0] += A;
    abcd[1] += B;
    abcd[2] += C;
    abcd[3] += D;
}

int main(int argc, char * argv[])
{
    judge_endian();

    if(argc != 2)
        return 1;

    FILE * f = fopen(argv[1], "rb");
    if(!f)
        return 2;

    uint32_t abcd[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };

    uint64_t bit_sum = 0;

    for(;;) {
        char buf[128];
        size_t n = fread(buf, 1, 64, f);
        bit_sum += n * 8;

        if(n == 64) {
            md5_calc(abcd, (void *)buf);
        } else {
            memset(buf + n, 0, 128 - n);
            buf[n] = 0x80;

            uint64_t * end = (void *)( n < 56  ? &buf[64] : &buf[128]);
            end[-1] = is_big_endian ? cvt64(bit_sum) : bit_sum;

            md5_calc(abcd, (void *)buf);
            if(n >= 56)
                md5_calc(abcd, (void *)&buf[64]);

            break;
        }
    }

    fclose(f);

    int i;
    for(i = 0; i < 4; i++)
        printf("%08x", cvt32(abcd[i]));
    printf("\n");

    return 0;
}


练习 md5sum

标签:

原文地址:http://my.oschina.net/2bit/blog/511588

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!