文档章节

适合单片机的MD5源码

h
 houj
发布于 2014/10/15 17:30
字数 883
阅读 164
收藏 0

适合单片机的MD5源码

/*
 * MD5.h
 *
 *  Created on: 2013-1-29
 *      Author: HouJ
 */

#ifndef MD5_H_
#define MD5_H_
extern void md5_md5(const unsigned char* data, int len,unsigned char * md5Out);
#endif /* MD5_H_ */

#include <string.h>

#include "MD5.h"
//这个适合单片机

typedef unsigned char BYTE;
typedef unsigned long UINT;
typedef UINT MD5_SUB_ARRAY[16];
typedef UINT MD5_TRANSORM_FUNC(UINT, UINT, UINT);
typedef struct {
   UINT abcd[4];
   MD5_SUB_ARRAY sub_array;
} MD5_TRANSFORM_PARAM;

const static UINT MD5_TRANSFORM_MATRIX[4][16][3] = { { { 0, 7, 1 }, { 1, 12, 2 }, { 2, 17, 3 }, { 3, 22, 4 }, { 4, 7, 5 }, { 5, 12, 6 }, { 6, 17, 7 }, { 7, 22, 8 }, { 8, 7, 9 }, { 9, 12, 10 }, { 10, 17, 11 }, { 11, 22, 12 }, { 12, 7, 13 }, { 13, 12, 14 }, { 14, 17, 15 }, { 15, 22, 16 }, },

{ { 1, 5, 17 }, { 6, 9, 18 }, { 11, 14, 19 }, { 0, 20, 20 }, { 5, 5, 21 }, { 10, 9, 22 }, { 15, 14, 23 }, { 4, 20, 24 }, { 9, 5, 25 }, { 14, 9, 26 }, { 3, 14, 27 }, { 8, 20, 28 }, { 13, 5, 29 }, { 2, 9, 30 }, { 7, 14, 31 }, { 12, 20, 32 }, },

{ { 5, 4, 33 }, { 8, 11, 34 }, { 11, 16, 35 }, { 14, 23, 36 }, { 1, 4, 37 }, { 4, 11, 38 }, { 7, 16, 39 }, { 10, 23, 40 }, { 13, 4, 41 }, { 0, 11, 42 }, { 3, 16, 43 }, { 6, 23, 44 }, { 9, 4, 45 }, { 12, 11, 46 }, { 15, 16, 47 }, { 2, 23, 48 }, },

{ { 0, 6, 49 }, { 7, 10, 50 }, { 14, 15, 51 }, { 5, 21, 52 }, { 12, 6, 53 }, { 3, 10, 54 }, { 10, 15, 55 }, { 1, 21, 56 }, { 8, 6, 57 }, { 15, 10, 58 }, { 6, 15, 59 }, { 13, 21, 60 }, { 4, 6, 61 }, { 11, 10, 62 }, { 2, 15, 63 }, { 9, 21, 64 }, }, };

const static UINT MD5_TRANSFORM_ARRAY[65] = { //
      //
            0, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, //
            0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, //
            0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, //
            0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x2441453, 0xd8a1e681, //
            0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, //
            0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, //
            0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, //
            0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, //
            0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, //
            0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, //
            0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };

static inline UINT F(UINT x, UINT y, UINT z) {
   return ((x & y) | ((~x) & z));
}

static inline UINT G(UINT x, UINT y, UINT z) {
   return ((x & z) | (y & (~z)));
}

static inline UINT H(UINT x, UINT y, UINT z) {
   return (x ^ y ^ z);
}

static inline UINT I(UINT x, UINT y, UINT z) {
   return (y ^ (x | (~z)));
}

static void MD5_transform(MD5_TRANSFORM_PARAM* param, int ring, MD5_TRANSORM_FUNC func) {
   UINT a, b, c, d, s, k, i;
   UINT* abcd = param->abcd;
   UINT *X;
   const UINT* T;
   int index;
   X = param->sub_array;
   T = MD5_TRANSFORM_ARRAY;

   for (index = 0; index < 16; index++) {
      a = abcd[(3 * index + 0) & 3];
      b = abcd[(3 * index + 1) & 3];
      c = abcd[(3 * index + 2) & 3];
      d = abcd[(3 * index + 3) & 3];

      k = MD5_TRANSFORM_MATRIX[ring][index][0];
      s = MD5_TRANSFORM_MATRIX[ring][index][1];
      i = MD5_TRANSFORM_MATRIX[ring][index][2];

      a = a + func(b, c, d) + X[k] + T[i];
      a = (a << s) | (a >> (32 - s)); // 循环左移
      a = a + b;

      abcd[(3 * index + 0) & 3] = a;
   }
}

extern void md5_md5(const unsigned char* data, int len, unsigned char * md5Out) {
   int x, new_len;
   MD5_TRANSFORM_PARAM param;
   UINT ABCD[4] = { 0x67452301L, 0xefcdab89L, 0x98badcfeL, 0x10325476L };
   //计算时的数据布局
   //1)原始数据
   //2)填充数据(如果需要,最后数据长度不是64字节对齐,就需要填充),第一字节为0x80,其它为0
   //3)长度bit数,就是len*8,占用8字节
   new_len = (((len + 8) >> 6) + 1) << 6;
   unsigned char* ts = (unsigned char*) param.sub_array;
   for (x = 0; x < new_len; x += 64) {
      memcpy(param.abcd, ABCD, 16);
      if (x + 64 <= len) {
         //数据
         memcpy(ts, &data[x], 64);
      }
      else {
         //1)剩余数据
         memcpy(ts, &data[x], len - x);
         //2)填充的第一字节0x80
         if (new_len - len > 9) {
            ts[len - x] = 0x80;
         }
         //2)填充0
         memset(&ts[len - x + 1], 0, new_len - len - 9);
         //3)附加长度数据bit放到最后
         *(UINT*) (ts + 56) = len * 8;
         memset(ts + 60, 0, 4);
      }
      MD5_transform(&param, 0, F);
      MD5_transform(&param, 1, G);
      MD5_transform(&param, 2, H);
      MD5_transform(&param, 3, I);

      ABCD[0] += param.abcd[0];
      ABCD[1] += param.abcd[1];
      ABCD[2] += param.abcd[2];
      ABCD[3] += param.abcd[3];
   }
   memcpy(md5Out, ABCD, 16);
}

//========下面是测试代码
#include <stdio.h>
static void MD5(const void* ps) {
   int len = strlen((char*) ps);
   unsigned char rs[16];
   md5_md5((unsigned char*) ps, len, rs);

   const static char CS[] = "0123456789ABCDEF";
   char ss[33];
   int io = 0;
   for (int i = 0; i < 16; i++) {
      ss[io++] = CS[(rs[i] >> 4) & 0xF];
      ss[io++] = CS[(rs[i] >> 0) & 0xF];
   }
   ss[io++] = 0;
   printf("%s => %s\n", (char*) ps, ss);
}

int main() {
   MD5(""); //D41D8CD98F00B204E9800998ECF8427E
   MD5("a"); //0CC175B9C0F1B6A831C399E269772661
   MD5("b"); //92EB5FFEE6AE2FEC3AD71C777531578F
   MD5("abc"); //900150983CD24FB0D6963F7D28E17F72
   MD5("message digest"); //F96B697D7CB7938D525A2F31AAF161D0
   MD5("abcdefghijklmnopqrstuvwxyz"); //C3FCD3D76192E4007DFB496CCA67E13B
   MD5("20121026000000005284583160120B29"); //971F196C1627CDD67C4FC1B8B848F977
   MD5("20121026000000005284582F9E120B29"); //1184BFF2C4C5A5FBDF5ECB6E9B87CA1D
   MD5("20121026000000005284582F9E120B28"); //4050E36E5E2BBAFB907EC4E60EB16746
   MD5("20121026000000005284582F9E120B2820121026000000005284582F9E120B281"); //06956F20436B82B74D7AAB5D9C7011E6
   MD5("123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); //0DE3B4CBD2A8339F6DF2301CA885BB4D
   return 0;
}

© 著作权归作者所有

h
粉丝 9
博文 81
码字总数 57985
作品 0
长沙
技术主管
私信 提问
STC12单片机串口U盘测试程序源码

开发工具: C++ 对象: 51单片机 文件: STC12单片机串口测试程序源码 文件说明: www.usbing.net 为了便于用户熟悉优博士串口U盘USB118AD模块,帮助用户快速使用UART串口进行通信,我们特别...

dataie456000
2015/12/01
70
0
如何让单片连入互联网,然后进行远程操作

现在都在讲究什么物联网,远程监控,其实这种技术很早以前就已经存在了,比如说基于CAN总线的操作之类的东西。只是那种都是在工业中用的比较广泛而已,没有面对普通的消费者而已。 废话不多说...

天蓬小猪
2015/05/30
447
11
基于51单片机的简易示波器(STC89C51 ADC0804 12864 )

资料下载: http://download.csdn.net/download/feng3121/10265549 里面有单片机原理图,51源码(里面有大量注释,不管有没有做示波器都可以一看) 之前玩单片机,有一阵子一直想知道到底某个...

feng3121
2018/03/01
0
0
arm开发板上的驱动程序 提问

在ok6410的开发板上想驱动一个led灯,我不知道该怎么做,因为开发板自带的linux源码中貌似已经包含了很多设备的驱动程序,然后我自己想学写linux下的驱动,所以就想像单片机那样去控制一个l...

Ann123
2011/08/19
2.4K
5
一个将十六进制转换为二进制字符数组的函数

十六进制数转换为二进制数组的函数HexToBinStr 函数实现: 实际应用: 实际运行结果: 历史精选文章: Jlink使用技巧之读取STM32内部的程序 Jlink使用技巧之单独下载HEX文件到单片机 Jlink使...

whik
01/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis 源码(二)Mybatis 初始化

Mybatis 初始化是由SqlSessionFactoryBuilder来完成的,主要的工作解析XML文件,并将解析的类容封装到Configuration类中,最后将Configuration类封装到SqlSessionFactory中并返回,自此初始化...

xiaolyuh
26分钟前
9
0
约瑟夫环问题

约瑟夫环问题的原来描述为,设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,...

mskk
36分钟前
5
0
JEP解读与尝鲜系列1 - Java Valhalla与Java Inline class

涉及到的JEP: Project Valhalla JEP 169: Value Objects JEP 218: Generics over Primitive Types 这些特性将在JDK14实现 Valhalla项目背景 最主要的一点就是,让Java适应现代硬件:在Java语...

zhxhash
38分钟前
10
0
总结:Redis集群

一、redis集群方案 Master-slave方式,Master和Slave的数据一致,Slave从Master同步数据,然后通过Sentinal(哨兵)监控Master和Slave的健康状态,当异常的时候迅速切换,如Master宕机的时候...

浮躁的码农
41分钟前
7
0
三个盘子的汉诺塔

package base;/** * 汉诺塔 */public class TowerApp { static int nDisks = 3; public static void main(String[] args) { doTowers(nDisks, 'A','B',......

clean123
42分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部