C语言实现MD5加密算法

来源:互联网 发布:当前连接网络受限制 编辑:程序博客网 时间:2024/05/16 19:06

转载声明:http://blog.csdn.net/haroroda/article/details/45935099


  这次我分享的是MD5加密算法。其实MD5这个大名在还没上密码学课之前我就听说过了,那时我才刚学PHP,视频里面的讲师说像密码这种重要的信息要用md5()函数处理下再存数据库,这么一说起来其实MD5算是我接触的第一个现代密码呢害羞

     考虑到可能有些人是为了科普一下才点进来看的,我还是结合自身经验和课本知识把MD5加密原理讲一下把,MD5算法的具体过程有以下4步:

    (1)附加填充位 

      课本原话:填充一个‘1’和若干个‘0’使其长度模512与448同余,然后再将消息的真实长度以64bit表示附加在填充结果后面,从而使得消息长度恰好为512bit的整数倍。(不知道这段话你们看懂没有,方正我看了很久才看懂的,大概以前语文真的是体育老师教的哭

      举例说明吧:

      如明文为iscbupt

      其16ascII码是105,115,99,98,117,112,116,转换成二进制便是01101001 01110011 01100011 01100010 01110101 01110000 01110100,这是长度为56,要使其长度模512与448同余,则需补充一个‘1’和391个‘0’。因为消息长度为56,所以用64位二进制表示为00110000   00~00(56个‘0’)。到目前为止512位全部填充完整了~

    (2)初始化链接变量 

      课本原话:MD5中有A、B、C、D 4个32为寄存器,最开始存放4个固定的32位的整数参数,即初始链接变量,这些参数用于第1轮运算。

      A=0x12345678,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210

   (3)分组处理(迭代压缩)  

     课本原话:MD5算法的分组处理(压缩函数)与分组密码的分组处理相似。它由4轮组成,512bit的消息分组Mi被分成16个子分组(每个子分组为32bit)参与每轮16步函数运算,即每轮包括16个步骤。每步的输入是4个32bit的链接变量(插句话~也就是A、B、C、D)和一个32bit的消息分组(是Mi哦~~),输出为32位值。经过4轮共64步后,得到的4个寄存器值分别与输入链接变量(也就是初始的A、B、C、D)进行模加,即是当前消息的中间散列值。

     明文是iscbupt的Mi如下:

     M0:01101001 01110011 01100011 01100010

     M1:01110101 01110000 01110100 10000000

     M2:00000000 00000000 00000000 00000000

     ................

     M14:00111000 00000000 00000000 00000000

     M15:00000000 00000000 00000000 00000000

   (4)步函数

     由于课本的图无法上传,那这里就由我来说下啦~~

     所有大轮(上文所说的4轮)里的所有小轮(16轮)都是同一个步函数A=B+((A+f(B,C,D)+M[j]+T[i])<<<s)) 即B、C、D进入f函数(这里的f函数就是课本里的非线性函数,包含F、G、H、I这四种函数),得到的结果与A模加,与M[j]模加(这里的j与第几大轮第几小轮有关),与T[i]模加(这里的i从1取到64),然后进行循环左移(左移的2位数也与第几大轮第几小轮有关),再与B模加,最后得到的结果赋值给A。

    一小轮结束后将A赋值给B,B赋值给C,C赋值给D,原本的D赋值给A,赋值完的A、B、C、D便可以进入下一轮。

    下面来说下上文j、左移步数step、T[i]的取值情况:

     第一大轮:

      j在这大轮是按顺序从0取到15

     第1、5、9、13小轮step=7;第2、6、10、14小轮step=12;第3、7、11、15小轮step=17;第4、8、12、16小轮step=22

      第二大轮:

      j的取值顺序为-----1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 

     第1、5、9、13小轮step=5;第2、6、10、14小轮step=9;第3、7、11、15小轮step=14;第4、8、12、16小轮step=20

     第三大轮:

     j的取值顺序为----- 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 

     第1、5、9、13小轮step=4;第2、6、10、14小轮step=11;第3、7、11、15小轮step=16;第4、8、12、16小轮step=23

     第四大轮:

      j的取值顺序为-----0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9

      第1、5、9、13小轮step=6;第2、6、10、14小轮step=10;第3、7、11、15小轮step=15;第4、8、12、16小轮step=21

     T[i]= 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 
   
   MD5的加密原理到这里就讲完了,下面来说下注意事项,也是我这次编程发现的一些理解的误区(这些结论是在明文长度不大于448的情况下成了,大于448是否成立我并没有验证过..):

      1.MD5加密算法里面的所有模加都是模2的32次加,而不是模2加。举例说明下模2的32次加:如11101000......(省略了24个‘0’)+01110000.........(省略了24个‘0’)=101011000.......(省略了24个‘0’),共33位,取后32位最终得到01011000........(省略了24个‘0’)。

      2.初始的A、B、C、D 4个链接变量与M[j]在进入步函数前要先经过大小端处理,T[i]不需要。

      3.位数填充时(64bit),若长度的二进制位数不足,需要在二进制前补齐至8的整数倍而不是4的整数倍。如400=110010000

补齐后是00000001 10010000而不是00011001 00000000

      4.大小端处理不是单纯指12345678->78563412,之所以有前面这种变换,是因为12、34、56、78分别表示4个十进制数,也就是说表示第1个十进制数的十六进制数经过转换放在最后,第2个放在第1个前。。当1234表示第1个十进制数、5678表示第2个十进制数时,12345678->56781234而不是78563412。如:明文长度为400,M[14]为0x01900000,转换后为0x00000190而不是0x00009001


     下面附上代码(输入的明文字符个数不大于64)

[cpp] view plain copy
  1. #include<stdio.h>  
  2.   
  3. /*各函数声明*/  
  4. void shizhuaner(int in, int n, int *md5);  
  5. void shizhuaner_weishu(int in, int *md5);  
  6. void shiliuzhuaner(char *t, int *temp);  
  7. void c_out(int *a);  
  8. void abcd_out(int *a);  
  9. void F(int *b, int *c, int *d, int *temp1, int *temp2);  
  10. void G(int *b, int *c, int *d, int *temp1, int *temp2);  
  11. void H(int *b, int *c, int *d, int *temp);  
  12. void I(int *b, int *c, int *d, int *temp);  
  13. void yu(int *a, int *b, int *temp);  
  14. void huo(int *a, int *b, int *temp);  
  15. void fei(int *a, int *temp);  
  16. void yihuo(int *a, int *b, int *temp);  
  17. void jia(int *a, int *b, int *temp);  
  18.   
  19. /*十进制转二进制函数*/  
  20. void shizhuaner(int in, int n, int *md5)  
  21. {  
  22.     int j, s, w;    
  23.     s = n / 4 + 1;  //s是md5里面组的排位数,w是该组里面的位数  
  24.     w = n % 4;  
  25.     j = 1;  
  26.     do  
  27.     {  
  28.         md5[32 * s - 8 * w - j] = in % 2;  
  29.         in = in / 2;  
  30.         j++;  
  31.     } while (in != 0);  
  32.     while (j <=8)  //二进制不够八位时补零  
  33.     {  
  34.         md5[32 * s - 8 * w - j] = 0;  
  35.         j++;  
  36.     }  
  37. }  
  38.   
  39. /* 位数填充时所用到的十进制转二进制函数 */  
  40. void shizhuaner_weishu(int in, int *md5)  
  41. {  
  42.     int i,j,temp, a[64];  
  43.     for (i = 0; in!= 0; i++)  
  44.     {  
  45.         a[i] = in % 2;  
  46.         in = in / 2;  
  47.     }  
  48.     while (i % 8 != 0)  //二进制位数不够八的整数倍时补零  
  49.     {  
  50.         a[i] = 0;  
  51.         i++;  
  52.     }  
  53.     for (j = 0; j <i/2; j++)  
  54.     {  
  55.         temp = a[i - j - 1];  
  56.         a[i - j-1] = a[j];  
  57.         a[j] = temp;  
  58.           
  59.     }  
  60.     temp = i/8;  
  61.     for (i=i-1; i < 64; i++)  
  62.         a[i] = 0;  
  63.     for (i = 0; i < 4; i++)   
  64.     {  
  65.         for (j = 0; j < 8; j++)  
  66.             md5[512 - temp * 8 + j - 32] = a[i * 8 + j];  
  67.         temp = temp - 1;  
  68.     }  
  69.     for (i = 0; i < 4; i++)  
  70.     {  
  71.         for (j = 0; j < 8; j++)  
  72.             md5[512 - (i + 1) * 8 + j ] = a[i * 8 + j+32];  
  73.     }  
  74. }  
  75.   
  76. /* 十六进制转二进制函数 */  
  77. void shiliuzhuaner(char *t, int *temp)  
  78. {  
  79.     int i;  
  80.     for (i = 0; i < 8; i++)  
  81.     {  
  82.         switch (t[i])  
  83.         {  
  84.         case '0':{temp[4 * i] = 0; temp[4 * i + 1] = 0; temp[4 * i + 2] = 0; temp[4 * i + 3] = 0; }break;  
  85.         case '1':{temp[4 * i] = 0; temp[4 * i + 1] = 0; temp[4 * i + 2] = 0; temp[4 * i + 3] = 1; }break;  
  86.         case '2':{temp[4 * i] = 0; temp[4 * i + 1] = 0; temp[4 * i + 2] = 1; temp[4 * i + 3] = 0; }break;  
  87.         case '3':{temp[4 * i] = 0; temp[4 * i + 1] = 0; temp[4 * i + 2] = 1; temp[4 * i + 3] = 1; }break;  
  88.         case '4':{temp[4 * i] = 0; temp[4 * i + 1] = 1; temp[4 * i + 2] = 0; temp[4 * i + 3] = 0; }break;  
  89.         case '5':{temp[4 * i] = 0; temp[4 * i + 1] = 1; temp[4 * i + 2] = 0; temp[4 * i + 3] = 1; }break;  
  90.         case '6':{temp[4 * i] = 0; temp[4 * i + 1] = 1; temp[4 * i + 2] = 1; temp[4 * i + 3] = 0; }break;   
  91.         case '7':{temp[4 * i] = 0; temp[4 * i + 1] = 1; temp[4 * i + 2] = 1; temp[4 * i + 3] = 1; }break;  
  92.         case '8':{temp[4 * i] = 1; temp[4 * i + 1] = 0; temp[4 * i + 2] = 0; temp[4 * i + 3] = 0; }break;  
  93.         case '9':{temp[4 * i] = 1; temp[4 * i + 1] = 0; temp[4 * i + 2] = 0; temp[4 * i + 3] = 1; }break;  
  94.         case 'a':{temp[4 * i] = 1; temp[4 * i + 1] = 0; temp[4 * i + 2] = 1; temp[4 * i + 3] = 0; }break;  
  95.         case 'b':{temp[4 * i] = 1; temp[4 * i + 1] = 0; temp[4 * i + 2] = 1; temp[4 * i + 3] = 1; }break;  
  96.         case 'c':{temp[4 * i] = 1; temp[4 * i + 1] = 1; temp[4 * i + 2] = 0; temp[4 * i + 3] = 0; }break;  
  97.         case 'd':{temp[4 * i] = 1; temp[4 * i + 1] = 1; temp[4 * i + 2] = 0; temp[4 * i + 3] = 1; }break;  
  98.         case 'e':{temp[4 * i] = 1; temp[4 * i + 1] = 1; temp[4 * i + 2] = 1; temp[4 * i + 3] = 0; }break;  
  99.         case 'f':{temp[4 * i] = 1; temp[4 * i + 1] = 1; temp[4 * i + 2] = 1; temp[4 * i + 3] = 1; }break;     
  100.         }  
  101.     }  
  102. }  
  103.   
  104. /* 密文输出函数 */  
  105. void c_out(int *a)  
  106. {  
  107.     int i,add;  
  108.     for (i = 1; i <= 4; i++)  //二进制转换成十六进制输出  
  109.     {  
  110.         add = a[32 - i * 8] * 8 + a[32 - i * 8 + 1] * 4 + a[32 - i * 8 + 2] * 2 + a[32 - i * 8 + 3];  
  111.         if (add >= 10)  
  112.         {  
  113.             switch (add)  
  114.             {  
  115.             case 10:printf("a"); break;  
  116.             case 11:printf("b"); break;  
  117.             case 12:printf("c"); break;  
  118.             case 13:printf("d"); break;  
  119.             case 14:printf("e"); break;  
  120.             case 15:printf("f"); break;  
  121.             }  
  122.         }  
  123.         else  
  124.             printf("%d", add);  
  125.         add = a[32 - i * 8+4] * 8 + a[32 - i * 8 + 5] * 4 + a[32 - i * 8 + 6] * 2 + a[32 - i * 8 + 7];  
  126.         if (add >= 10)  
  127.         {  
  128.             switch (add)  
  129.             {  
  130.             case 10:printf("a"); break;  
  131.             case 11:printf("b"); break;  
  132.             case 12:printf("c"); break;  
  133.             case 13:printf("d"); break;  
  134.             case 14:printf("e"); break;  
  135.             case 15:printf("f"); break;  
  136.             }  
  137.         }  
  138.         else  
  139.             printf("%d", add);  
  140.     }  
  141. }  
  142.   
  143. /* 中间过程的输出函数 */  
  144. void abcd_out(int *a)  
  145. {  
  146.     int i, add;  
  147.     for (i = 0; i < 4; i++)  //二进制转换成十六进制输出  
  148.     {  
  149.         add = a[i * 8] * 8 + a[i * 8 + 1] * 4 + a[i * 8 + 2] * 2 + a[i * 8 + 3];  
  150.         if (add >= 10)  
  151.         {  
  152.             switch (add)  
  153.             {  
  154.             case 10:printf("a"); break;  
  155.             case 11:printf("b"); break;  
  156.             case 12:printf("c"); break;  
  157.             case 13:printf("d"); break;  
  158.             case 14:printf("e"); break;  
  159.             case 15:printf("f"); break;  
  160.             }  
  161.         }  
  162.         else  
  163.             printf("%d", add);  
  164.         add = a[i * 8 + 4] * 8 + a[i * 8 + 5] * 4 + a[i * 8 + 6] * 2 + a[i * 8 + 7];  
  165.         if (add >= 10)  
  166.         {  
  167.             switch (add)  
  168.             {  
  169.             case 10:printf("a"); break;  
  170.             case 11:printf("b"); break;  
  171.             case 12:printf("c"); break;  
  172.             case 13:printf("d"); break;  
  173.             case 14:printf("e"); break;  
  174.             case 15:printf("f"); break;  
  175.             }  
  176.         }  
  177.         else  
  178.             printf("%d", add);  
  179.     }  
  180. }  
  181.   
  182. /* 与函数 */  
  183. void yu(int *a, int *b,int *temp)  
  184. {  
  185.     int i;  
  186.     for (i = 0; i < 32; i++)  //同为1为1,否则为0  
  187.     {  
  188.         if (a[i] == 1 && b[i] == 1)  
  189.             temp[i] = 1;  
  190.         else  
  191.             temp[i] = 0;  
  192.     }  
  193. }  
  194.   
  195. /* 或函数 */  
  196. void huo(int *a, int *b, int *temp)  
  197. {  
  198.     int i;  
  199.     for (i = 0; i < 32; i++)  //同0为0,否则为1  
  200.     {  
  201.         if (a[i] == 0 && b[i] == 0)  
  202.             temp[i] = 0;  
  203.         else  
  204.             temp[i] = 1;  
  205.     }  
  206. }  
  207.   
  208. /* 非函数 */  
  209. void fei(int *a, int *temp)  
  210. {  
  211.     int i;  
  212.     for (i = 0; i < 32; i++)    
  213.     {  
  214.         if (a[i] == 0)  
  215.             temp[i] = 1;  
  216.         else  
  217.             temp[i] = 0;  
  218.     }  
  219. }  
  220.   
  221. /*异或函数*/  
  222. void yihuo(int *a, int *b, int *temp)  
  223. {  
  224.     int i;  
  225.     for (i = 0; i < 32; i++)  //相同为0,不同为1  
  226.     {  
  227.         if (a[i] != b[i])  
  228.             temp[i] = 1;  
  229.         else  
  230.             temp[i] = 0;  
  231.     }  
  232. }  
  233.   
  234. /* 模二的32次加 */  
  235. void jia(int *a, int *b, int *temp)  
  236. {  
  237.     int i,jin;  
  238.     jin = 0;  
  239.     for (i = 0; i < 32; i++)  
  240.     {  
  241.         if (a[31 - i] + b[31 - i] + jin>1)  
  242.         {  
  243.             temp[31 - i] = a[31 - i] + b[31 - i] + jin - 2;  
  244.             jin = 1;  
  245.         }  
  246.         else  
  247.         {  
  248.             temp[31 - i] = a[31 - i] + b[31 - i]+jin;  
  249.             jin = 0;  
  250.         }  
  251.     }  
  252. }  
  253.   
  254. /* F函数 */  
  255. void F(int *b, int *c, int *d,int *temp1,int *temp2)  
  256. {  
  257.     /* F(x,y,z)=(x∧y)∨(¬x∧z) */  
  258.     yu(b, c, temp1);  
  259.     fei(b, temp2);  
  260.     yu(temp2, d, temp2);  
  261.     huo(temp1, temp2, temp2);  
  262. }  
  263.   
  264. /* G函数 */  
  265. void G(int *b, int *c, int *d, int *temp1, int *temp2)  
  266. {  
  267.     /* G(x,y,z)=(x∧z)∨(y∧¬z) */  
  268.     yu(b, d, temp1);  
  269.     fei(d, temp2);  
  270.     yu(temp2, c, temp2);  
  271.     huo(temp1, temp2, temp2);  
  272. }  
  273.   
  274. /* H函数 */  
  275. void H(int *b, int *c, int *d, int *temp)  
  276. {  
  277.     /* H(x,y,z)=x⊕y⊕z */  
  278.     yihuo(b, c, temp);  
  279.     yihuo(temp, d, temp);  
  280. }  
  281.   
  282. /* I函数 */  
  283. void I(int *b, int *c, int *d, int *temp)  
  284. {  
  285.     /* I(x,y,z)=y⊕(x∨¬z) */  
  286.     fei(d, temp);  
  287.     huo(b, temp, temp);  
  288.     yihuo(c, temp, temp);  
  289. }  
  290.   
  291. /*左移函数*/  
  292. void move(int step, int *temp1, int *temp2)  
  293. {  
  294.     int i;  
  295.     for (i = 0; i < 32 - step; i++)  
  296.         temp2[i] = temp1[i + step];  
  297.     for (i = 0; i < step; i++)  
  298.         temp2[32 - step + i] = temp1[i];  
  299. }  
  300.   
  301. /*每一大轮的16小轮循环函数*/  
  302. void round(int *a, int *b, int *c, int *d, int *m, int *md5, int r, char *t1,   
  303.     char *t2, char *t3, char *t4, char *t5, char *t6, char *t7, char *t8, char *t9,   
  304.     char *t10, char *t11, char *t12, char *t13, char *t14, char *t15, char *t16 )  
  305. {  
  306.     int i, j, in, step , temp1[32], temp2[32];  
  307.     for (i = 0; i < 16; i++)  
  308.     {  
  309.         switch (r)  //根据r判断所选的逻辑函数  
  310.         {  
  311.         case 1:F(b, c, d, temp1, temp2); break;  
  312.         case 2:G(b, c, d, temp1, temp2); break;  
  313.         case 3:H(b, c, d, temp2); break;  
  314.         case 4:I(b, c, d, temp2); break;  
  315.         }  
  316.         in = m[i];  
  317.         for (j = 0; j < 32; j++)  
  318.             temp1[j] = md5[in * 32 + j];  
  319.         jia(temp2, temp1, temp2);  
  320.         switch (i + 1)  //选择t[]  
  321.         {  
  322.         case 1:shiliuzhuaner(t1, temp1); break;  
  323.         case 2:shiliuzhuaner(t2, temp1); break;  
  324.         case 3:shiliuzhuaner(t3, temp1); break;  
  325.         case 4:shiliuzhuaner(t4, temp1); break;  
  326.         case 5:shiliuzhuaner(t5, temp1); break;  
  327.         case 6:shiliuzhuaner(t6, temp1); break;  
  328.         case 7:shiliuzhuaner(t7, temp1); break;  
  329.         case 8:shiliuzhuaner(t8, temp1); break;  
  330.         case 9:shiliuzhuaner(t9, temp1); break;  
  331.         case 10:shiliuzhuaner(t10, temp1); break;  
  332.         case 11:shiliuzhuaner(t11, temp1); break;  
  333.         case 12:shiliuzhuaner(t12, temp1); break;  
  334.         case 13:shiliuzhuaner(t13, temp1); break;  
  335.         case 14:shiliuzhuaner(t14, temp1); break;  
  336.         case 15:shiliuzhuaner(t15, temp1); break;  
  337.         case 16:shiliuzhuaner(t16, temp1); break;  
  338.         }  
  339.         jia(temp2, temp1, temp2);  
  340.         jia(temp2, a, temp2);  
  341.         switch(r)  //根据r为左移步数step赋值  
  342.         {    
  343.         case 1:switch (i % 4 + 1){ case 1:step = 7; breakcase 2:step = 12; breakcase 3:step = 17; breakcase 4:step = 22; break; }break;  
  344.         case 2:switch (i % 4 + 1){ case 1:step = 5; breakcase 2:step = 9; breakcase 3:step = 14; breakcase 4:step = 20; break; }break;  
  345.         case 3:switch (i % 4 + 1){ case 1:step = 4; breakcase 2:step = 11; breakcase 3:step = 16; breakcase 4:step = 23; break; }break;  
  346.         case 4:switch (i % 4 + 1){ case 1:step = 6; breakcase 2:step = 10; breakcase 3:step = 15; breakcase 4:step = 21; break; }break;  
  347.         }  
  348.         move(step, temp2, temp1);  
  349.         jia(temp1, b, temp2);  
  350.         for (j = 0; j < 32; j++)  
  351.         {  
  352.             a[j] = d[j];  
  353.             d[j] = c[j];  
  354.             c[j] = b[j];  
  355.             b[j] = temp2[j];  
  356.         }  
  357.   
  358.         /*若想输出每轮a、b、c、d的值,把下面的注释取消即可*/  
  359.         /*printf("第%d大轮的第%d小轮\n", r, i); 
  360.         abcd_out(a); 
  361.         printf("   "); 
  362.         abcd_out(b); 
  363.         printf("   "); 
  364.         abcd_out(c); 
  365.         printf("   "); 
  366.         abcd_out(d); 
  367.         printf("\n");*/  
  368.   
  369.     }  
  370. }  
  371.   
  372. /* 主函数 */  
  373. int main()  
  374. {  
  375.     char ch,  
  376.         /* 一大坨t[] */  
  377.         t1[8] = { 'd''7''6''a''a''4''7''8' },  
  378.         t2[8] = { 'e''8''c''7''b''7''5''6' },  
  379.         t3[8] = { '2''4''2''0''7''0''d''b' },  
  380.         t4[8] = { 'c''1''b''d''c''e''e''e' },  
  381.         t5[8] = { 'f''5''7''c''0''f''a''f' },  
  382.         t6[8] = { '4''7''8''7''c''6''2''a' },  
  383.         t7[8] = { 'a''8''3''0''4''6''1''3' },  
  384.         t8[8] = { 'f''d''4''6''9''5''0''1' },  
  385.         t9[8] = { '6''9''8''0''9''8''d''8' },  
  386.         t10[8] = { '8''b''4''4''f''7''a''f' },  
  387.         t11[8] = { 'f''f''f''f''5''b''b''1' },  
  388.         t12[8] = { '8''9''5''c''d''7''b''e' },  
  389.         t13[8] = { '6''b''9''0''1''1''2''2' },  
  390.         t14[8] = { 'f''d''9''8''7''1''9''3' },  
  391.         t15[8] = { 'a''6''7''9''4''3''8''e' },  
  392.         t16[8] = { '4''9''b''4''0''8''2''1' },  
  393.         t17[8] = { 'f''6''1''e''2''5''6''2' },  
  394.         t18[8] = { 'c''0''4''0''b''3''4''0' },  
  395.         t19[8] = { '2''6''5''e''5''a''5''1' },  
  396.         t20[8] = { 'e''9''b''6''c''7''a''a' },  
  397.         t21[8] = { 'd''6''2''f''1''0''5''d' },  
  398.         t22[8] = { '0''2''4''4''1''4''5''3' },  
  399.         t23[8] = { 'd''8''a''1''e''6''8''1' },  
  400.         t24[8] = { 'e''7''d''3''f''b''c''8' },  
  401.         t25[8] = { '2''1''e''1''c''d''e''6' },  
  402.         t26[8] = { 'c''3''3''7''0''7''d''6' },  
  403.         t27[8] = { 'f''4''d''5''0''d''8''7' },  
  404.         t28[8] = { '4''5''5''a''1''4''e''d' },  
  405.         t29[8] = { 'a''9''e''3''e''9''0''5' },  
  406.         t30[8] = { 'f''c''e''f''a''3''f''8' },  
  407.         t31[8] = { '6''7''6''f''0''2''d''9' },  
  408.         t32[8] = { '8''d''2''a''4''c''8''a' },  
  409.         t33[8] = { 'f''f''f''a''3''9''4''2' },  
  410.         t34[8] = { '8''7''7''1''f''6''8''1' },  
  411.         t35[8] = { '6''d''9''d''6''1''2''2' },  
  412.         t36[8] = { 'f''d''e''5''3''8''0''c' },  
  413.         t37[8] = { 'a''4''b''e''e''a''4''4' },  
  414.         t38[8] = { '4''b''d''e''c''f''a''9' },  
  415.         t39[8] = { 'f''6''b''b''4''b''6''0' },  
  416.         t40[8] = { 'b''e''b''f''b''c''7''0' },  
  417.         t41[8] = { '2''8''9''b''7''e''c''6' },  
  418.         t42[8] = { 'e''a''a''1''2''7''f''a' },  
  419.         t43[8] = { 'd''4''e''f''3''0''8''5' },  
  420.         t44[8] = { '0''4''8''8''1''d''0''5' },  
  421.         t45[8] = { 'd''9''d''4''d''0''3''9' },  
  422.         t46[8] = { 'e''6''d''b''9''9''e''5' },  
  423.         t47[8] = { '1''f''a''2''7''c''f''8' },  
  424.         t48[8] = { 'c''4''a''c''5''6''6''5' },  
  425.         t49[8] = { 'f''4''2''9''2''2''4''4' },  
  426.         t50[8] = { '4''3''2''a''f''f''9''7' },  
  427.         t51[8] = { 'a''b''9''4''2''3''a''7' },  
  428.         t52[8] = { 'f''c''9''3''a''0''3''9' },  
  429.         t53[8] = { '6''5''5''b''5''9''c''3' },  
  430.         t54[8] = { '8''f''0''c''c''c''9''2' },  
  431.         t55[8] = { 'f''f''e''f''f''4''7''d' },  
  432.         t56[8] = { '8''5''8''4''5''d''d''1' },  
  433.         t57[8] = { '6''f''a''8''7''e''4''f' },  
  434.         t58[8] = { 'f''e''2''c''e''6''e''0' },  
  435.         t59[8] = { 'a''3''0''1''4''3''1''4' },  
  436.         t60[8] = { '4''e''0''8''1''1''a''1' },  
  437.         t61[8] = { 'f''7''5''3''7''e''8''2' },  
  438.         t62[8] = { 'b''d''3''a''f''2''3''5' },  
  439.         t63[8] = { '2''a''d''7''d''2''b''b' },  
  440.         t64[8] = { 'e''b''8''6''d''3''9''1' };  
  441.     int in, n = 0, i,j,addup;  
  442.     int md5[512],  
  443.         /*每一大轮m[]的调用顺序*/  
  444.         m1[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },  
  445.         m2[16] = { 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 },  
  446.         m3[16] = { 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 },  
  447.         m4[16] = { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 },  
  448.         /* a[]、b[]、c[]、d[]的初始值(已经过大小端处理) */  
  449.         /* 把a[]、b[]、c[]、d[]赋值给a1[]、b1[]、c1[]、d1[]*/  
  450.         a[32] = { 0, 1, 1, 0, 0, 1, 1, 1,  
  451.         0, 1, 0, 0, 0, 1, 0, 1,  
  452.         0, 0, 1, 0, 0, 0, 1, 1,  
  453.         0, 0, 0, 0, 0, 0, 0, 1 },  
  454.         a1[32] = { 0, 1, 1, 0, 0, 1, 1, 1,  
  455.         0, 1, 0, 0, 0, 1, 0, 1,  
  456.         0, 0, 1, 0, 0, 0, 1, 1,  
  457.         0, 0, 0, 0, 0, 0, 0, 1 },  
  458.         b[32] = { 1, 1, 1, 0, 1, 1, 1, 1,  
  459.         1, 1, 0, 0, 1, 1, 0, 1,  
  460.         1, 0, 1, 0, 1, 0, 1, 1,  
  461.         1, 0, 0, 0, 1, 0, 0, 1 },  
  462.         b1[32] = { 1, 1, 1, 0, 1, 1, 1, 1,  
  463.         1, 1, 0, 0, 1, 1, 0, 1,  
  464.         1, 0, 1, 0, 1, 0, 1, 1,  
  465.         1, 0, 0, 0, 1, 0, 0, 1 },  
  466.         c[32] = { 1, 0, 0, 1, 1, 0, 0, 0,  
  467.         1, 0, 1, 1, 1, 0, 1, 0,  
  468.         1, 1, 0, 1, 1, 1, 0, 0,  
  469.         1, 1, 1, 1, 1, 1, 1, 0 },  
  470.         c1[32] = { 1, 0, 0, 1, 1, 0, 0, 0,  
  471.         1, 0, 1, 1, 1, 0, 1, 0,  
  472.         1, 1, 0, 1, 1, 1, 0, 0,  
  473.         1, 1, 1, 1, 1, 1, 1, 0 },  
  474.         d[32] = { 0, 0, 0, 1, 0, 0, 0, 0,  
  475.         0, 0, 1, 1, 0, 0, 1, 0,  
  476.         0, 1, 0, 1, 0, 1, 0, 0,  
  477.         0, 1, 1, 1, 0, 1, 1, 0 },  
  478.         d1[32] = { 0, 0, 0, 1, 0, 0, 0, 0,  
  479.         0, 0, 1, 1, 0, 0, 1, 0,  
  480.         0, 1, 0, 1, 0, 1, 0, 0,  
  481.         0, 1, 1, 1, 0, 1, 1, 0 };  
  482.     printf("请输入需加密的明文(长度不大于56)\n");  
  483.     ch = getchar();  
  484.     while (ch!='\n'&&n<57)  //用getchar()函数接收字符,直到接收到回车符或字符数超过56为止  
  485.     {  
  486.         in = (int)ch;  
  487.         shizhuaner(in, n, md5);  
  488.         n++;  
  489.         ch = getchar();  
  490.     }  
  491.     i = 0;  
  492.     addup = n;  
  493.     while (n% 4 != 0 && n<56)  //长度不是4的倍数,补一个1和0直到长度为4的倍数,,最终实现用1与0使其长度模512与448同于,在这个程序里也就是448  
  494.     {  
  495.         int s, w, j;  
  496.         s = n / 4 + 1;  
  497.         w = n % 4;  
  498.         j = 1;  
  499.         do  
  500.         {  
  501.             md5[32 * s - 8 * w - j] = 0;  
  502.             j++;  
  503.         } while (j<=7);  
  504.         if (i == 0)  
  505.         {  
  506.             md5[32 * s - 8 * w - j] = 1;    
  507.             i = 1;  
  508.         }  
  509.         n++;  
  510.     }  
  511.     if (i == 0)  //长度不是4的倍数,补一个1和31个0  
  512.     {  
  513.         for (j = 0; j < 32; j++)  
  514.             md5[n * 8 + j] = 0;  
  515.         md5[8 * n + 24] = 1;  
  516.     }  
  517.     for (i = 0; i < 512; i++)  //补零,任何不为1的数都设为0  
  518.     {  
  519.         if (md5[i] == 1)  
  520.             md5[i] = 1;  
  521.         else  
  522.             md5[i] = 0;  
  523.     }  
  524.     printf("\n");  
  525.     shizhuaner_weishu(addup * 8, md5);  //64位数填充  
  526.   
  527.     /*若想看m[0]~m[15],把下面注释去掉即可*/  
  528.     /*printf("m[0]~m[15]如下:\n"); 
  529.     for (i = 0; i < 512; i++) 
  530.     { 
  531.         printf("%d ", md5[i]); 
  532.         if (i % 8 == 7) 
  533.             printf("\n"); 
  534.         if (i % 32 == 31) 
  535.             printf("\n"); 
  536.     } 
  537.     printf("\n");*/  
  538.   
  539.     /* 第一、二、三、四大轮,每一大轮下有16小轮 */  
  540.     round(a, b, c, d, m1, md5, 1, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16);  
  541.     round(a, b, c, d, m2, md5, 2, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32);  
  542.     round(a, b, c, d, m3, md5, 3, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48);  
  543.     round(a, b, c, d, m4, md5, 4, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59, t60, t61, t62, t63, t64);  
  544.     printf("\n");  
  545.     /* 最终的a、b、c、d分别与最初的a、b、c、d相加 */  
  546.     jia(a, a1, a);  
  547.     jia(b, b1, b);  
  548.     jia(c, c1, c);  
  549.     jia(d, d1, d);  
  550.     /*密文输出*/  
  551.     printf("密文:\n");  
  552.     c_out(a);  
  553.     c_out(b);  
  554.     c_out(c);  
  555.     c_out(d);  
  556.     printf("\n");  
  557.     return 0;  
  558. }  

运行结果:

示例1


示例2


示例3



使用说明:

1.因为我对位运算不是很了解,所以这份代码是没有使用位运算的。如果看时觉得混乱可以发邮件给我

2.默认情况下这份代码是不输出M[0]~M[15]和4大轮16小轮中A、B、C、D的变化情况的,如果想输出以上内容的话,在适当的位置取消注释便可(代码中有注释说明位置)


0 0