MD5加密原理解析及OC版原理实现

  一、MD5算法基础概念

  MD5算法是Hash算法的一种,叫做讯息摘要演算法。所谓摘要,从字面意思理解,是指内容的大概。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息。并且其是不可逆的,即从摘要信息无法反向推演中原文,在演算过程中,原文的内容也是有丢失的。

  因为MD5算法最终生成的是一个128位长的数据,从原理上说,有2^128种可能,这是一个非常巨大的数据,约等于3.4乘10的38次方,虽然这个是个天文数字,但是世界上可以进行加密的数据原则上说是无限的,因此是可能存在不同的内容经过MD5加密后得到同样的摘要信息,但这个碰中的概率非常小。

  二、MD5的使用场景

  MD5常用在密码加密中,一般为了保证用户密码的安全,在数据库中存储的都是用户的密码经过MD5加密后的值,在客户端用户输入密码后,也会使用MD5进行加密,这样即使用户的网络被窃听,窃听者依然无法拿到用户的原始密码,并且即使用户数据库被盗,没有存储明文的密码对用户来说也多了一层安全保障。

  MD5签名技术还常用于防止信息的篡改。使用MD5可以对进行进行签名,接收者拿到信息后只要重新计算签名和原始签名进行对比,即可知道数据信息是否中途被篡改了。

  三、MD5算法原理

  MD5算法大致分为4步完成:

  第1步:进行数据填充整理

  这一步是对要加密的数据进行填充和整理,将要加密的二进制数据对512取模,得到的结果如果不够448位,则进行补足,补足的方式是第1位填充1,后面全部填充0。

  第2步:记录数据长度

  经过第一步整理完成后的数据的位数可以表示为N*512+448,再向其后追加64位用来存储数据的长度,比如数据的长度为16字节,则用10000来填充后64位。这一步做完后,数据的位数将变成(N+1)*512。

  第3步:以标准的幻数作为输入

  MD5的实现需要每512个字节进行一次处理,后一次处理的输入为前一次处理的输出,因此,在循环处理开始之前,需要拿4个标准数作为输入,它们分别是:

  unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476;

  第4步:进行N轮循环处理,将最后的结果输出

  这一步重要的是每一轮的处理算法,每一轮处理也要循环64次,这64次循环被分为4各组,每16次循环为一组,每组循环使用不同的逻辑处理函数,处理完成后,将输出作为输入进入下一轮循环。

  四、MD5核心算法的实现

  这里演示的是每轮循环的核心算法:

  首先进行3个函数的声明:

  //将大端字节序转换为小端字节序

  void convertToLittleEndian(unsigned int *data, int len);

  //进行循环左移函数

  void ROL(unsigned int *s, unsigned short cx);

  //MD5加密函数

  void MD5(NSString *str);

  MD5算法中处理的数据都是小端字节序的,而使用Objective-C处理的NSData对象的字节序是大端字节序,因此我们需要做一下转换。函数实现如下:

  void convertToLittleEndian(unsigned int *data, int len)

  {

  for (int index = 0; index < len; index ++) {

  *data = ((*data & 0xff000000) >> 24)

  | ((*data & 0x00ff0000) >>  8)

  | ((*data & 0x0000ff00) <<  8)

  | ((*data & 0x000000ff) << 24);

  data ++;

  }

  }

  在MD5中有需要对字节数据进行循环左移的操作,循环左移函数实现如下:

  void ROL(unsigned int *s, unsigned short cx)

  {

  if (cx > 32)cx %= 32;

  *s = (*s << cx) | (*s >> (32 - cx));

  return;

  }

  下面是MD5函数的核心实现:

  void MD5(NSString *str){

  const void * bytes[str.length];

  //字符串转字节流

  [str getBytes:bytes maxLength:str.length usedLength:nil encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, str.length) remainingRange:nil];

  //使用NSData存储

  NSMutableData * data = [[NSMutableData alloc] initWithBytes:bytes length:str.length];

  BOOL first = YES;

  //进行数据填充

  if (data.length<56) {

  do {

  if (first) {

  int byte = 0b10000000;

  [data appendBytes:&byte length:1];

  first = NO;

  }else{

  int byte = 0b00000000;

  [data appendBytes:&byte length:1];

  }

  } while (data.length<56);

  }

  int length = (int)str.length*8%((int)pow(2, 64));

  [data appendBytes:&length length:8];

  void * newBytes[64];

  memcpy(newBytes, [data bytes], 64);

  //大小端转换

  convertToLittleEndian(newBytes, 64);

  NSData * newData = [NSData dataWithBytes:newBytes length:data.length];

  NSMutableArray * subData = [NSMutableArray array];

  //进行分组

  for (int i = 0; i<16; i++) {

  [subData addObject: [newData subdataWithRange:NSMakeRange(i*4, 4)]];

  }

  //初始输入

  unsigned int A=0x67452301,B=0xefcdab89, www.dasheng178.com=0x98badcfe,D=0x10325476;

  unsigned int a=A,b=B,c=C,d=D;

  unsigned int s[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 };

  unsigned int  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,www.hengda157.com  0xa3014314, 0x4e0811a1,

  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };

  //64次循环处理

  for (int i = 0; i <= 64; i++) {

  if (i<64) {

  unsigned int f;

  unsigned int g;

  if (i<16) {

  f = (b&c)|((~b)&d);

  g = i;

  }else if(i<32) {

  f = (b&d)|((~d)&c);

  g = (5*i+1)%16;

  }else if(i<48){

  f = b^c^d;

  g = (3*i+5)%16;

  }else{

  f = c^((~d)|b);

  g = (7*i)%16;

  }

  unsigned int * temp www.michenggw.com= (unsigned int *) [subData[g] bytes];

  unsigned int  *tem = malloc(sizeof(unsigned int));

  memcpy(tem, temp, 4);

  convertToLittleEndian(tem, 4);

  unsigned int res = (a+f+*tem+k[i]);

  ROL(&res,s[i]);

  unsigned int t www.078881.cn = res+b;

  a = d;

  d = c;

  c = b;

  b = t;

  }else{

  A = a+A;

  B = b+B;

  C = c+C;

  D = d+D;

  }

  }

  //大小端转换

  unsigned int * newA = malloc(sizeof(unsigned int));

  memcpy(newA, &A, 4);

  NSLog(@"%0x",*newA);

  convertToLittleEndian(newA, 4);

  unsigned int * newB = malloc(sizeof(unsigned int));

  memcpy(newB, &B, 4);

  convertToLittleEndian(newB, 4);

  unsigned int * newC = malloc(sizeof(unsigned int));

  memcpy(newC, &C, 4);

  convertToLittleEndian(www.mhylpt.com newC, 4);

  unsigned int * newD = malloc(sizeof(unsigned int));

  memcpy(newD, &D, 4);

  convertToLittleEndian(newD, 4);

  NSLog(@"AAA:%0x %0x %0x %0x ",*newA,*newB,*newC,*newD);

MD5加密原理解析及OC版原理实现相关推荐

  1. MD5加密工具类(实战版)

    MD5加密工具类(实战版) 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成 ...

  2. 索引算法原理解析(B-tree以及磁盘存储原理)

    刚开始学习的时候,百度去查,但发现好多说得太复杂不好理解,结合各个文章总结一下(建议大概看文字,不理解不要紧,然后再看图的执行步骤然后在结合文字,这样一切就清晰好多) B-tree,B是balance ...

  3. 原理解析_SpringBoot自动装配原理解析

    自动装配是Spring Boot的核心部分,也是Spring Boot功能的基础,正是由于自动装配,才将我们从Bean的繁复配置中解脱出来.那么Spring Boot中的自动装配指的是什么?我们继 续 ...

  4. 超级狗 加密工具解析(正式版)

    超级狗 加密工具全面解析 SuperDog 一.超级狗工具开发套件: 1.超级狗工具的简介. 2.超级狗开发套件(光盘). ①.超级狗工具使用手册(PDF). ②.Android.Linux.Wind ...

  5. Vue3的响应式原理解析

    Vue3的响应式原理解析 Vue2响应式原理回顾 // 1.对象响应化:遍历每个key,定义getter.setter // 2.数组响应化:覆盖数组原型方法,额外增加通知逻辑 const origi ...

  6. 爱加密Android APk 原理解析

    转载请标明出处:http://blog.csdn.net/u011546655/article/details/45921025 爱加密Android APK加壳原理解析 一.什么是加壳? 加壳是在二 ...

  7. flask web开发是前端还是后端_Flask Web开发实战:入门、进阶与原理解析 PDF 全格式版...

    给大家带来的一篇关于Flask相关的电子书资源,介绍了关于Flask.Web.开发实战方面的内容,本书是由机械工业出版社出版,格式为PDF,资源大小12.2M,李辉编写,目前豆瓣.亚马逊.当当.京东等 ...

  8. 详细过程MD5加密的原理+java实现

    MD5加密 加密原理 大端小端 算法 代码实现 加密原理 大端小端 一个字节是8位即0000 0000,它能表示2^8=256个数,最大的数为255,那我们如果要表示数256,就需要两个字节即16位, ...

  9. 【IoT】加密与安全:哈希 Hash 算法用途与原理解析

    1.Hash 算法分类 MD5 和 SHA-1 是目前应用最广泛的 Hash 算法且是以 MD4 算法为基础设计的. 1) MD4 MD4(RFC 1320) 是 MIT 的 Ronald L. Ri ...

最新文章

  1. python爬虫下载文件-【Py大法系列--03】Python如何自动下载文件
  2. java中的静态代码块、构造代码块、构造方法
  3. P3160 [CQOI2012]局部极小值
  4. vue---数据列表循环
  5. 来字节一年多,我都经历了什么?
  6. delphi 侧边栏_Delphi 开发工具各版本官方下载地址
  7. 不要再学 JSP 了,学 SpringBoot + Thymeleaf + Vue吧
  8. 飞到半路被撞?不是小鸟不专心,而是太阳能太晃眼
  9. Android 键盘快捷键
  10. 基于注意力机制超分辨率汇总
  11. WebAssembly 实践:如何写代码
  12. java 毛笔字,Photoshop设计唯美大气的毛笔字
  13. photoshop使用技巧_如何使用Photoshop创建逼真的漫画
  14. RGB与YCbCr颜色空间的转换
  15. Velocity User Guide 用户手册
  16. 八、码元、波特、速率和带宽
  17. 敏感性、特异度、α、β、阳性预测值(PPV)、阴性预测值(NPV)等指标及置信区间计算(附R语言代码)
  18. Android的数据存储:SharedPrefrence存储,手机内部文件存储,手机外部文件存储
  19. 小程序.silk转MP3格式
  20. 静态工具类使用单例对象线程安全问题注意1

热门文章

  1. SpringBoot整合Mybatis逆向工程
  2. ansys apdl建模案例2-----------齿轮
  3. 华为畅享20pro和华为nova7se的区别 哪个好
  4. 20220322在MT6739的android8.1下增加ll命令
  5. 云游戏就是云未来,阿里元境 x Unity x 长江学者这样说
  6. 集夜视仪、望远镜、显微镜于一身,这是手机还是相机?
  7. 为Gerrit Code review添加verified标签
  8. Python + Appium 自动化测试(二):实战
  9. SpringBoot的Web开发入门案例5—注册Servlets, Filter, Listener
  10. windows10 多桌面的两个方法(利用键盘或鼠标)