博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MD5算法实现
阅读量:6759 次
发布时间:2019-06-26

本文共 2569 字,大约阅读时间需要 8 分钟。

MD5算法的简要叙述为:

MD5以512位分组来处理输入的信息(512位分组?每次处理都取出512位数据?),

每一分组又被划分为16个32位子分组(16乘32刚好是512),

经过一些列的处理后(怎么处理的?),算法的输出由四个32位分组组成,

将这4个32位分组级联后将生成一个128位的散列值(那么这个散列值是最后的加密结果咯)。

 

在MD5算法中,首先需要对信息进行填充,使其位长度对512求余的结果等于448。

因此,信息的位长度(Bits Length)将被扩展至N*512+448,即N*64+56个字节(Bytes),N是一个正整数。

填充方法如下:

在信息的后面填一个和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。

(这里的信息长度应该是位长度吧?)。经过这两步的处理,现在的信息字节长度=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。

这样也是为了满足后面处理中对信息长度的要求。

MD5中有4个32为被称为链接变量(Chaining Variable)的整数参数,它们分别是:

A=0x01234567,

B=0x89abcdef,

C=0xfedcba98,

D=0x76543210,

(这四个数是大端法表示的!每一个变量给出的数值是高字节存于内存低地址,低字节存于内存高地址,即大端字节序。

在程序中变量A、B、C、D的值分别为0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,马丹,这里有点搞不清白)

当设置好这四个链接变量之后,就开始进入算法的四轮循环运算。循环的次数是信息中512位信息分组的数目。

(也就是说经过填充之后的数据位数是512的整数倍,然后按照顺序每次取出512位拿过来进行四轮处理)

将上面4个链接变量复制到另外4个变量中:A到a,B到b,C到c,D到d。

主循环有四轮(MD4只有三轮,三轮车?),每轮循环都很相似。

第一轮进行16次操作。每次操作对a、b、c和d中的3个做一次非线性函数运算,然后将所得的结果依次加上第四个变量、文本的一个子分组和一个常数。

再将所得的结果向右循环移动一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。

下面是每次操作中用到的四个非线性函数(每轮一个)。

F(X, Y, Z) = (X & Y) | ((~X) & Z)

G(X, Y, Z) = (X  & Z) | (Y & (~Z))

H(X, Y, Z) = X^Y^Z

I(X, Y, Z) = Y^(X | (~Z))

(&是与,|是或,~是非,^是异或)

这四个函数的说明:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。

F是一个逐位运算的函数。即,如果X,那么Y,否则Z。

H是逐位奇偶操作符。

假设Mj表示消息的第j个子分组(从0到15),

FF(a, b, c, d, Mj, s, ti)表示a = b + ((a + F(b, c, d) + Mj + ti) << s),

GG(a, b, c, d, Mj, s, ti)表示a = b + ((a + G(b, c, d) + Mj + ti) << s),

HH(a, b, c, d, Mj, s, ti)表示a = b + ((a + H(b, c, d) + Mj + ti) << s),

II(a, b, c, d, Mj, s, ti)表示a = b + ((a + I(b, c, d) + Mj + ti) << s),

(尼玛,这几个看着倒是挺对称的)

(<<是循环左移位,而不是左移位)

这四轮(一轮16步,取32位数处理,一共64步)是:

第一轮

第二轮

第三轮

第四轮

 

常数ti可以如下选择:

在第i步中,ti是4294967296*abs(sin(i))的整数部分,i的单位是弧度(4294967296等于2的32次方)。

在所有的这些都完成之后,将A、B、C、D分别加上a、b、c、d。然后用下一分组数据继续运行算法,最后的输出将是A、B、C和D的级联。

在Java中,java。security.MessageDigest中已经定义了MD5的计算,只需要简单地调用即可得到MD5的128位整数。

然后将此128位(16个字节)转换成十六进制表示即可。

 

package com.java.md5;public class MD5 {	public static String getMD5(byte[] source) {		String s = null;		char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a',				'b','c','d','e','f'};		try {			java.security.MessageDigest md = 					java.security.MessageDigest.getInstance("MD5");			md.update(source);			byte tmp[] = md.digest();			char str[] = new char[16*2];			int k = 0;			for (int i = 0; i < 16; i++) {				byte byte0 = tmp[i];				str[k++] = hexDigits[byte0 >>> 4 & 0xf];				str[k++] = hexDigits[byte0 & 0xf];			}			s = new String(str);		} catch(Exception e) {			e.printStackTrace();		}		return s;	}		public static void main(String[] args) {		String a = "I love you";		byte[] b = a.getBytes();		for (int i=0; i

转载地址:http://dtweo.baihongyu.com/

你可能感兴趣的文章
shell脚本的测试用法
查看>>
iOS 各种验证码
查看>>
我的友情链接
查看>>
我所理解的OOP——UML六种关系
查看>>
php--抓屏
查看>>
安装和测试scvmm 2012R2评估版--2scvmm 2012 R2的安装
查看>>
网站搬家MySql出现#1036 - Table ' ' is read only 错误提示
查看>>
关于我
查看>>
c++实现广义表
查看>>
centos7 安装apache+mysql+php环境
查看>>
Django 安全策略的 7 条总结!
查看>>
SylixOS网卡驱动调用篇
查看>>
gmail 授权linux服务器登录使用gmail发送邮件
查看>>
七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理
查看>>
shell -20180712
查看>>
性能优化技巧 - 程序游标
查看>>
oracle 静默建库、建监听
查看>>
优秀的 Go 存储开源项目和库
查看>>
Java笔试面试题(四)
查看>>
移动磁盘显示文件系统损坏要怎样找到文件
查看>>