zoukankan      html  css  js  c++  java
  • MD5哈希算法(C语言实现)

    MD5哈希算法(C语言实现)

    主要是做个记录,害怕以后代码丢了,先放到这里了。
    MD5 暂时就不进行介绍了,最基础的哈希算法,网上到处都是。
    转载请注明出处:https://www.cnblogs.com/wangyanzhong123/p/13784318.html

    说明

    这个版本用了很多位运算,也没有添加注释,所以可能阅读起来会有一些困难。但是可以保证的是结果一定是正确的,并且速度也是经过优化的,应该会很快。

    源代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h>
    #include <time.h>
    
    #define LEFTSHIFT(x,c) (((x) << (c)) | ((x) >> (32-(c))))
    
    const uint32_t k[64] = {
    0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
    0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
    0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
    0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
    0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
    0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
    0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
    0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
    0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
    0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
    0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
    0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
    0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
    0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
    0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
    0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
     
    // per-round shift amounts
    const uint32_t r[64] = {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};
    
    void to_bytes(uint32_t val, uint8_t *bytes){
        bytes[0] = (uint8_t) val;
        bytes[1] = (uint8_t) (val >> 8);
        bytes[2] = (uint8_t) (val >> 16);
        bytes[3] = (uint8_t) (val >> 24);
    }
    
    uint32_t to_int32(const uint8_t *bytes){
        return (uint32_t)bytes[0] 
        | ((uint32_t)bytes[1] << 8) 
        | ((uint32_t)bytes[2] << 16) 
        | ((uint32_t)bytes[3] << 24);
    }
    
    void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t* digest){
        size_t new_len, offset;
        uint32_t words[16];
        uint8_t *newmsg = NULL;
        uint32_t h0, h1, h2, h3, a, b, c, d, f, g, temp;
        h0 = 0x67452301;
        h1 = 0xefcdab89;
        h2 = 0x98badcfe;
        h3 = 0x10325476;
        // Pre-processing
        // calculate new length (not included last 8bytes)
        for (new_len = initial_len+1; new_len % (512/8) != 448/8; new_len++);
        newmsg = (uint8_t*)malloc(new_len+8); // 8 bytes for length recording
        memcpy(newmsg, initial_msg, initial_len);
        newmsg[initial_len]=0x80; // padding "1" first, then all "0"
        for (offset = initial_len+1; offset < new_len; offset++)
            newmsg[offset] = 0x00;
        // append the len in bits at the end of buffer ??? why << 3
        to_bytes(initial_len << 3, newmsg + new_len);
        to_bytes(initial_len >> 29, newmsg + new_len + 4);
    
        // process the message per 512-bits
        for (offset = 0; offset < new_len; offset += (512/8)){
            // break 512 bits into 16 words(32-bit)
            for (uint32_t i = 0; i < 16; i ++)
                words[i] = to_int32(newmsg + offset + i*4);
            a = h0; b = h1; c = h2; d = h3;
            for (uint32_t i = 0; i < 64; i ++){
                if (i < 16) {
                    f = (b & c) | ((~b) & d);
                    g =  i;
                } else if (i < 32) {
                    f = (d & b) | ((~d) & c);
                    g = (5*(i-16) + 1) % 16;
                } else if (i < 48) {
                    f = b ^ c ^ d;
                    g = (3*(i-32) + 5) % 16;
                } else {
                    f = c ^ (b | (~d));
                    g = (7*(i-48)) % 16;
                }
                temp = d;
                d = c;
                c = b;
                b = b + LEFTSHIFT((a+f+k[i]+words[g]), r[i]);
                a = temp;
            }
            h0 += a;
            h1 += b;
            h2 += c;
            h3 += d;
        }
        free(newmsg);
        to_bytes(h0, digest);
        to_bytes(h1, digest+4);
        to_bytes(h2, digest+8);
        to_bytes(h3, digest+12);
    }
    
    
    int main(int argc, char **argv){
        char *msg;
        clock_t start,finish;
        double duration;
        size_t msglen;
        uint8_t result[16];
        char *inputstring = "-s";
        char *inputfile = "-f";
        if (argc < 2){
            printf("usage: %s 'string'
    ", argv[0]);
            return 1;
        } else if (!strcmp(argv[1],inputstring)){
            msg = argv[2];
            msglen = strlen(msg);
            start = clock();
            md5((uint8_t*)msg, msglen, result);
            for (int i = 0; i < 16; i++)
                printf("%2.2x", result[i]);
            printf("
    ");
            finish = clock();
            duration = (double)(finish - start) / CLOCKS_PER_SEC;
            printf("time cost: %f
    ", duration);
            system("pause");
            return 0;
        } else if (!strcmp(argv[1],inputfile)){
            FILE *infile;
            infile = fopen(argv[2],"rb");
            if (infile == NULL){
                printf("%s not exist
    ",argv[2]);
                return -1;
            } else {
                fseek(infile, 0, SEEK_END);
                size_t filesize = ftell(infile);
                rewind(infile);
                uint8_t *buffer = (uint8_t*)malloc(sizeof(uint8_t)*filesize);
                fread(buffer, sizeof(uint8_t), filesize, infile);
                start = clock();
                md5(buffer, filesize, result);
                for (int i = 0; i < 16; i++)
                    printf("%2.2x", result[i]);
                printf("
    ");
                finish = clock();
                duration = (double)(finish - start) / CLOCKS_PER_SEC;
                printf("time cost: %f
    ", duration);
                system("pause");
                return 0;
            }
        }
    }
    
  • 相关阅读:
    dom4j的安装
    OWl本体语言学习笔记
    java学习笔记之链表(约瑟夫问题)
    C#打开指定文件夹及下载文件代码示例
    如何把phpStorm打造成自己的专属IDE
    SQL和TSQL之间的区别
    整数的划分(分治递归)
    整数的划分(变形)(分治递归)
    子序列 (Data_Structure)
    找球号(Hash)
  • 原文地址:https://www.cnblogs.com/wangyanzhong123/p/13784318.html
Copyright © 2011-2022 走看看