zoukankan      html  css  js  c++  java
  • MD5算法的C语言实现

    1

      1 #include <stdio.h>
      2 #include <stdint.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <sys/types.h>
      6 #include "md5.h"
      7 
      8 #ifdef __cplusplus
      9 extern "C" {
     10 #endif
     11 
     12 #define ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
     13 
     14 #define TO_HEX_FMT_L "%02x"
     15 #define TO_HEX_FMT_U "%02X"
     16 
     17 /**
     18  * @desc: convert message and mes_bkp string into integer array and store them in w 
     19  */
     20 static void md5_process_part1(uint32_t *w, const char *message, uint32_t *pos, uint32_t mes_len, const unsigned char *mes_bkp)
     21 {
     22     uint32_t i; // used in for loop
     23 
     24     for(i = 0; i <= 15; i++)
     25     {
     26         int32_t count = 0;
     27         while(*pos < mes_len && count <= 24)
     28         {
     29             w[i] += (((uint32_t)message[*pos]) << count);
     30             (*pos)++;
     31             count += 8;
     32         }
     33         while(count <= 24)
     34         {
     35             w[i] += (((uint32_t)mes_bkp[*pos - mes_len]) << count);
     36             (*pos)++;
     37             count += 8;
     38         }
     39     }
     40 }
     41 
     42 /**
     43  * @desc: start encryption based on w
     44  */
     45 static void md5_process_part2(uint32_t abcd[4], uint32_t *w, const uint32_t k[64], const uint32_t s[64])
     46 {
     47     uint32_t i; // used in for loop
     48 
     49     uint32_t a = abcd[0];
     50     uint32_t b = abcd[1];
     51     uint32_t c = abcd[2];
     52     uint32_t d = abcd[3];
     53     uint32_t f = 0;
     54     uint32_t g = 0;
     55 
     56     for(i = 0; i < 64; i++)
     57     {
     58         if(i >= 0 && i <= 15)
     59         {
     60             f = (b & c) | ((~b) & d);
     61             g = i;
     62         }else if(i >= 16 && i <= 31)
     63         {
     64             f = (d & b) | ((~d) & c);
     65             g = (5 * i + 1) % 16;
     66         }else if(i >= 32 && i <= 47)
     67         {
     68             f = b ^ c ^ d;
     69             g = (3 * i + 5) % 16;
     70         }else if(i >= 48 && i <= 63)
     71         {
     72             f = c ^ (b | (~d));
     73             g = (7 * i) % 16;
     74         }
     75         uint32_t temp = d;
     76         d = c;
     77         c = b;
     78         b = ROTATELEFT((a + f + k[i] + w[g]), s[i]) + b;
     79         a = temp;
     80     }
     81 
     82     abcd[0] += a;
     83     abcd[1] += b;
     84     abcd[2] += c;
     85     abcd[3] += d;
     86 }
     87 
     88 /**
     89  * @desc: format the output, convert numbers to hexdecimal string and store them in result
     90  */
     91 static void format_output(char *result, size_t size, uint32_t *abcd, uint32_t flag)
     92 {
     93     uint32_t i; // used in for loop
     94     
     95     memset(result, 0, size);
     96 
     97     uint32_t ptr = 0;
     98     for(i = 0; i < 4; i++)
     99     {
    100         ptr += snprintf(result + ptr, size - ptr, (flag == 0)?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x000000FF));
    101         ptr += snprintf(result + ptr, size - ptr, (flag == 0)?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x0000FF00) >> 8 );
    102         ptr += snprintf(result + ptr, size - ptr, (flag == 0)?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0x00FF0000) >> 16);
    103         ptr += snprintf(result + ptr, size - ptr, (flag == 0)?TO_HEX_FMT_U:TO_HEX_FMT_L, (abcd[i] & 0xFF000000) >> 24);
    104     }
    105 }
    106 
    107 
    108 /**
    109  * @input: result -- store the calculation result
    110  *         size   -- size of result. Make sure it's at least 33 
    111  *                   since the result is a 32-byte hexdecimal string.
    112  *         message-- string to be encrypted
    113  *         flag   -- 0 means upper case output, 1 means lower case output
    114  * @return: 0 -- success
    115  *          1 -- result size less than 33
    116  *          2 -- calloc failed
    117  */
    118 int32_t cal_md5(char *result, size_t size, const char *message, uint32_t flag){
    119     if (result == NULL || size < 33)
    120     {
    121         return 1;
    122     }
    123     
    124     uint32_t *w = (uint32_t *)calloc(16, sizeof(uint32_t));
    125     if(w == NULL)
    126     {
    127         return 2;
    128     }
    129 
    130     uint32_t i; // used in for loop
    131 
    132     uint32_t mes_len = strlen(message);
    133     uint32_t looptimes = (mes_len + 8) / 64 + 1;
    134     uint32_t abcd[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476};
    135 
    136     const uint32_t k[]={
    137         0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
    138         0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
    139         0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
    140         0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
    141         0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
    142         0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
    143         0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
    144         0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
    145         0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
    146         0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
    147         0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
    148         0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
    149         0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
    150     };
    151 
    152     const uint32_t s[]={
    153         7,12,17,22,7,12,17,22,7,12,17,22,7,
    154         12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
    155         4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
    156         15,21,6,10,15,21,6,10,15,21,6,10,15,21
    157     };
    158 
    159     uint32_t pos = 0; // position pointer for message string
    160     uint32_t bkp_len = 64 * looptimes - mes_len;
    161     unsigned char *bkp_mes = (unsigned char *)calloc(1, bkp_len);
    162     if(bkp_mes == NULL)
    163     {
    164         free(w);
    165         return 2;
    166     }
    167 
    168     bkp_mes[0] = (unsigned char)(0x80);
    169     uint64_t mes_bit_len = ((uint64_t)mes_len) * 8;
    170     for(i = 0; i < 8; i++)
    171     {
    172         bkp_mes[bkp_len-i-1] = (unsigned char)((mes_bit_len & (0x00000000000000FF << (8 * (7 - i)))) >> (8 * (7 - i)));
    173     }
    174     
    175     for(i = 0; i < looptimes; i++)
    176     {
    177         memset(w, 0, 16 * sizeof(uint32_t));
    178         
    179         md5_process_part1(w, message, &pos, mes_len, bkp_mes); // compute w
    180         
    181         md5_process_part2(abcd, w, k, s); // calculate md5 and store the result in abcd
    182     }
    183     
    184     free(w);
    185     free(bkp_mes);
    186 
    187     format_output(result, size, abcd, flag);
    188 
    189     return 0;
    190 }
    191 
    192 #ifdef __cplusplus
    193 }
    194 #endif

    2

     1 /**
     2  * @author Horst Xu
     3  * @date 2015-07-10
     4  * @contact 271021733@qq.com
     5  */
     6 #ifndef __MD5_H__
     7 #define __MD5_H__
     8 
     9 #include <stdint.h>
    10 #include <stddef.h>
    11 
    12 #ifdef __cplusplus
    13 extern "C" {
    14 #endif
    15 
    16 /**
    17  * @input: result -- store the calculation result
    18  *         size   -- size of result. Make sure it's at least 33 
    19  *                   since the result is a 32-byte hexdecimal string.
    20  *         message-- string to be encrypted
    21  *         flag   -- 0 means upper case output, 1 means lower case output
    22  * @return: 0 -- success
    23  *          1 -- result size less than 33
    24  *          2 -- calloc failed
    25  */
    26 int32_t cal_md5(char *result, size_t size, const char *message, uint32_t flag);
    27 
    28 #ifdef __cplusplus
    29 }
    30 #endif
    31 
    32 #endif //__MD5_H__

    3

     1 #include <stdio.h>
     2 #include <stdint.h>
     3 #include <string.h>
     4 
     5 #include "md5.h"
     6 
     7 int32_t main(void)
     8 {
     9     char result[41];
    10     int32_t ret = -1;
    11 
    12     //test 1
    13     ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz123", 1);
    14     if(ret == 0 && 0 == strncmp(result, "dd2fc541b65e2202d55beae0ecaf6528", strlen(result)))
    15     {
    16         printf("test 1 successful!
    ");
    17     }else
    18     {
    19         printf("test 1 failed!
    ");
    20     }
    21 
    22     //test 2
    23     ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz1234", 0);
    24     if(ret == 0 && 0 == strncmp(result, "27FF2E8344E7E3F36F9C7E18D0EC82DF", strlen(result)))
    25     {
    26         printf("test 2 successful!
    ");
    27     }else
    28     {
    29         printf("test 2 failed!
    ");
    30     }
    31 
    32     //test 3
    33     ret = cal_md5(result, sizeof(result), "abcdegfhijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz12345", 0);
    34     if(ret == 0 && 0 == strncmp(result, "7A7B1279343946E3A5949BEA1B3BF8AF", strlen(result)))
    35     {
    36         printf("test 3 successful!
    ");
    37     }else
    38     {
    39         printf("test 3 failed!
    ");
    40     }
    41 
    42     //test 4
    43     ret = cal_md5(result, sizeof(result), "", 1);
    44     if(ret == 0 && 0 == strncmp(result, "d41d8cd98f00b204e9800998ecf8427e", strlen(result)))
    45     {
    46         printf("test 4 successful!
    ");
    47     }else
    48     {
    49         printf("test 4 failed!
    ");
    50     }
    51 
    52     return 0;
    53 }
  • 相关阅读:
    ElasticSearch原理
    redis master配置了密码进行主从同步
    redis sentinel 高可用(HA)方案部署,及python应用示例
    Linux Redis集群搭建与集群客户端实现
    字符串倒序
    单链表反转
    【python】面试常考数据结构算法
    面试中的排序算法总结
    Memcached 真的过时了吗?
    Activity生命周期
  • 原文地址:https://www.cnblogs.com/xuning/p/4686021.html
Copyright © 2011-2022 走看看