基于JavaScript实现MD5散列函数辅助计算器

基于JavaScript实现MD5散列函数辅助计算器

 

因为最近在学信息加密技术,搞清楚了加密原理,但又不想手动去计算,所以就用JavaScript写了一个网页版的MD5散列函数的辅助计算器,计算器的输入与输出都是16进制形式。

当然,因为我需要的是每一轮每一步的结果,所以计算器每一次运行只能计算一步。

首先,MD5的散列原理:

(1)填充消息:任意长度的消息首先需要进行填充处理,使得填充后的消息总长度与448模512同余。填充的方法是在消息后面添加一位1,后续都是0.

(2)添加原始消息长度:在填充后的消息后面再添加一个64位的二进制整数表示填充前原始消息的长度,第(1)步跟第(2)完成之后刚好消息的长度为512位。

(3)初始值(IV)的初始化MD5中有四个32位缓冲区,用A,B,C,D表示,用来存散列计算的中间结果和最终结果,缓冲区的值被称为链接变量。先将其分别初始化为:A=0x1234567、B=0x89abcdef、C=0xfedcba98、D=0x76543210,这些值以高端格式存储,即字节的最高有效位存于低地址字节位置。

(4)以512位的分组为单位,依据四个非线性函数对消息进行循环散列计算,四轮共64步计算。

非线性函数:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(F(B,C,D)+M+T)<<<s)
                     F(X,Y,Z)=(X&Y)|((非B)&Z)

            GG(A,B,C,D,M,s,t) 表示 A = B+(A+(G(B,C,D)+M+T)<<<s)
            G(X,Y,Z)=(X&Z)|(Y&(非Z))

            HH(A,B,C,D,M,s,t) 表示 A = B+(A+(H(B,C,D)+M+T)<<<s)
            H(X,Y,Z)=(X^Y^Z)

            II(A,B,C,D,M,s,t) 表示 A = B+(A+(I(B,C,D)+M+T)<<<s)
            I(X,Y,Z)=Y^(X|(非Z)

(5)输出散列值。

写的这个计算器就是属于第(4)、第(5)部分。

 

计算器涉及到的内容有html网页、css样式表、JavaScript函数等基础操作。

主界面:七个输入数据的文本框框,一个结果文本框,四个计算按钮,一个显示公式的多行文本框           

其中M[j]是填充后的消息分组;S是循环左移的位数;T[I]是常数,在下面。

b365b5cebe494ad18e7ad2e8e167135f.png

 a3c1f8a603c14300b82602470d3346c3.png

 

主界面代码:利用了css盒子来进行布局;引用了一个外部样式表和三个外部js文件

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>MD5迭代计算</title>
	<link rel="stylesheet" type="text/css" href="样式表.css">
	<script type="text/javascript" src="zhuhanshu.js"></script>
	<script type="text/javascript" src="进制转换.js"></script>
	<script type="text/javascript" src="逻辑运算.js"></script>
</head>
<body>
	<div><!---创建输入框   -->
		<div id="box1">MD5散列函数辅助计算器(16进制)</div>
		<div id="box2">**********每一次运行只计算一次**********</div>
		<div id="box3">
			<div id="box3_1">输入A:<input type="text" id="shu_1" onkeyup="UpperCase(this.id)"></div>
			<div id="box3_2">输入B:<input type="text" id="shu_2" onkeyup="UpperCase(this.id)"></div>
		</div>
		<div id="box3">
			<div id="box3_1">输入C:<input type="text" id="shu_3" onkeyup="UpperCase(this.id)"></div>
			<div id="box3_2">输入D:<input type="text" id="shu_4" onkeyup="UpperCase(this.id)"></div>
		</div>
		<div id="box3">
			<div id="box3_1">输入M[j]:<input type="text" id="shu_5" onkeyup="UpperCase(this.id)"></div>
			<div id="box3_2">输入S:<input type="text" id="shu_6"></div>
		</div>
		<div id="box3">
			<div id="box3_1">输入T[i]:<input type="text" id="shu_7" onkeyup="UpperCase(this.id)"></div>
			<div id="box3_2">计算结果:<input type="text" id="shu_8"></div>
		</div>
		<div id="box4">
			<!---创建事件按钮   -->
			<div id="box4_1"><button onclick="FFjisuan()"><font size="6"> FF计算 </font></button></div>
			<div id="box4_1"><button onclick="GGjisuan()"><font size="6"> GG计算 </font></button></div>
			<div id="box4_1"><button onclick="HHjisuan()"><font size="6"> HH计算 </font></button></div>
			<div id="box4_1"><button onclick="IIjisuan()"><font size="6"> II计算 </font></button></div>
		</div>
		<div id="textarea">
			<textarea rows="12" cols="100">
			公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(F(B,C,D)+M+T)<<<s)
			F(X,Y,Z)=(X&Y)|((非B)&Z)>

			公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(G(B,C,D)+M+T)<<<s)
			G(X,Y,Z)=(X&Z)|(Y&(非Z))>

			公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(H(B,C,D)+M+T)<<<s)
			H(X,Y,Z)=(X^Y^Z)>

			公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(I(B,C,D)+M+T)<<<s)
			I(X,Y,Z)=Y^(X|(非Z)>
			</textarea>
		</div>
	</div>
</body>
</html>

 

外部样式表代码:

input
{
	width: 350px;
	height: 30px;
	font-size: 30PX;
}

#box1{
	font-size: 50px;
	font-weight: bold;
	font-family: "隶书";
	margin-left: 30%;
	
}
#box2{
	font-size: 30px;
	color: red;
	font-weight: bold;
	margin-left: 28%;
	
}
#box3{
	font-size: 50px;
	font-weight: bold;
	width:100%;
	height: 100px;
	text-align: center;
}
#box3_1{
	font-size: 30px;
	font-weight: bold;
	width:50%;
	height: 100px;
	float: left;
	background-color: #00FFFF;
}
#box3_2{
	font-size: 30px;
	font-weight: bold;
	width:50%;
	height: 100px;
	float: left;
	background-color: #87CEFA;
}
#box4{
	width:100%;
	height: 50px;
	text-align: center;
	padding: 20px;
}
#box4_1{
	width:10%;
	height: 50px;

	position: relative;
	background: #009ACD;
	border: 0;
	color: #DDA07A;
	padding: 20px 25px;
	font-size: 20px;

	box-shadow: -6px 6px 0 ;  
	float: left;
	text-align: center;
	margin-left: 7%;
}

#textarea
{
	float: left;
	width:100%;
	height: 20%;
	padding: 20px;
}

 

四个按钮点击事件代码:(依据四个非线性函数来写)

//主体函数
//
//第一轮计算函数
function FFjisuan()                    
{
		/*公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(F(B,C,D)+M+T)<<<s)
			F(X,Y,Z)=(X&Y)|((非B)&Z)
			 */
		//判断文本框是否为空
		var y = true;
		y = kong();
        if(y)
        {
			//获取输入框数据
			var a = document.getElementById("shu_1").value;
			var b = document.getElementById("shu_2").value;
			var c = document.getElementById("shu_3").value;
			var d = document.getElementById("shu_4").value;
			var m = document.getElementById("shu_5").value;
			var s = document.getElementById("shu_6").value;
			var t = document.getElementById("shu_7").value;
			        
			        			        			         			        			        
			 //16进制转换为2进制
			var A = tostring2(a); 
			var B = tostring2(b); 
			var C = tostring2(c); 
			var D = tostring2(d); 
			var M = tostring2(m); 
			var T = tostring2(t);  

			//对照公式逻辑运算
			var e = luojiyu(B,C);  //BC逻辑与运算
			var m = luojifei(B);   //B的非
			var f = luojiyu(m,D);   //B的非跟D逻辑与运算
			var g = luojihuo(e,f);    //逻辑或运算
			var h = yihuo(g,A);      //结果跟A异或运算
			var i = yihuo(h,M);      //结果跟M异或运算
			var j = yihuo(i,T);      //结果跟T异或运算
			var k = shiftLeft(j,s);  //循环左移
			var l = yihuo(k,B);     //结果跟B异或
			var n = tostring16(l);  //二进制转出为16进制
			document.getElementById("shu_8").value = n;  //输出结果
		}
}

//第二轮计算函数		
function GGjisuan()                    
{
		/*公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(G(B,C,D)+M+T)<<<s)
			G(X,Y,Z)=(X&Z)|(Y&(非Z))
			 */
		//判断文本框是否为空
		var y = true;
		y = kong();
        if(y)
        {

			//获取输入框数据
			var a = document.getElementById("shu_1").value;        
			var b = document.getElementById("shu_2").value;        
			var c = document.getElementById("shu_3").value;        
			var d = document.getElementById("shu_4").value;         
			var m = document.getElementById("shu_5").value;        
			var s = document.getElementById("shu_6").value;        
			var t = document.getElementById("shu_7").value;        
			
			 //16进制转换为2进制
			var A = tostring2(a); 
			var B = tostring2(b); 
			var C = tostring2(c); 
			var D = tostring2(d); 
			var M = tostring2(m); 
			var T = tostring2(t);  

			//对照公式逻辑运算
			var e = luojiyu(B,D);  //BD逻辑与运算
			var m = luojifei(D);   //D的非
			var f = luojiyu(m,C);   //D的非跟C逻辑与运算
			var g = luojihuo(e,f);    //逻辑或运算
			var h = yihuo(g,A);      //结果跟A异或运算
			var i = yihuo(h,M);      //结果跟M异或运算
			var j = yihuo(i,T);      //结果跟T异或运算
			var k = shiftLeft(j,s);  //循环左移
			var l = yihuo(k,B);     //结果跟B异或
			var n = tostring16(l);  //二进制转出为16进制
			document.getElementById("shu_8").value = n;  //输出结果
		}
}

//第三轮计算函数	
function HHjisuan()                    
{
			/*公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(H(B,C,D)+M+T)<<<s)
			H(X,Y,Z)=(X^Y^Z)
			 */
		//判断文本框是否为空
		var y = true;
		y = kong();
        if(y)
        {

			//获取输入框数据
			var a = document.getElementById("shu_1").value;        
			var b = document.getElementById("shu_2").value;        
			var c = document.getElementById("shu_3").value;        
			var d = document.getElementById("shu_4").value;         
			var m = document.getElementById("shu_5").value;        
			var s = document.getElementById("shu_6").value;        
			var t = document.getElementById("shu_7").value;        
			
			 //16进制转换为2进制
			var A = tostring2(a); 
			var B = tostring2(b); 
			var C = tostring2(c); 
			var D = tostring2(d); 
			var M = tostring2(m); 
			var T = tostring2(t);  

			//对照公式逻辑运算
			
			var e = yihuo(B,C);  //BC异或
			var m = yihuo(e,D);   //结果与D异或
			var h = yihuo(m,A);      //结果跟A异或运算
			var i = yihuo(h,M);      //结果跟M异或运算
			var j = yihuo(i,T);      //结果跟T异或运算
			var k = shiftLeft(j,s);  //循环左移
			var l = yihuo(k,B);     //结果跟B异或
			var n = tostring16(l);  //二进制转出为16进制
			document.getElementById("shu_8").value = n;  //输出结果
		}
}
//第四轮计算函数	
function IIjisuan()                    
{
			/*公式:FF(A,B,C,D,M,s,t) 表示 A = B+(A+(I(B,C,D)+M+T)<<<s)
			I(X,Y,Z)=Y^(X|(非Z)
			 */
			//判断文本框是否为空
		var y = true;
		y = kong();
        if(y)
        {

			//获取输入框数据
			var a = document.getElementById("shu_1").value;        
			var b = document.getElementById("shu_2").value;        
			var c = document.getElementById("shu_3").value;        
			var d = document.getElementById("shu_4").value;         
			var m = document.getElementById("shu_5").value;        
			var s = document.getElementById("shu_6").value;        
			var t = document.getElementById("shu_7").value;        
			
			 //16进制转换为2进制
			var A = tostring2(a); 
			var B = tostring2(b); 
			var C = tostring2(c); 
			var D = tostring2(d); 
			var M = tostring2(m); 
			var T = tostring2(t);  

			//对照公式逻辑运算
			var m = luojifei(D);   //D的非
			var e = luojihuo(B,m);  //B跟D的非逻辑或运算
			var g = yihuo(e,C);    //结果跟C异或运算
			var h = yihuo(g,A);      //结果跟A异或运算
			var i = yihuo(h,M);      //结果跟M异或运算
			var j = yihuo(i,T);      //结果跟T异或运算
			var k = shiftLeft(j,s);  //循环左移
			var l = yihuo(k,B);     //结果跟B异或
			var n = tostring16(l);  //二进制转出为16进制
			document.getElementById("shu_8").value = n;  //输出结果
		}
}

 

进制转换代码(16进制转2进制 和 2进制转16进制)

//将文本框中的小写字母转换为大写
function UpperCase(x)
{
	var a = document.getElementById(x).value;
	document.getElementById(x).value = a.toUpperCase();
}

//16进制转换2进制
function tostring2(str){
	var  val = "";
	var b =str.split('');
	for(var i =0;i<b.length;i++)
	{
		switch(b[i]){
			case "0":  val += "0000";break;
			case "1":  val += "0001";break;
			case "2":  val += "0010";break;
			case "3":  val += "0011";break;
			case "4":  val += "0100";break;
			case "5":  val += "0101";break;
			case "6":  val += "0110";break;
			case "7":  val += "0111";break;
			case "8":  val += "1000";break;
			case "9":  val += "1001";break;
			case "A":  val += "1010";break;
			case "B":  val += "1011";break;
			case "C":  val += "1100";break;
			case "D":  val += "1101";break;
			case "E":  val += "1110";break;
			case "F":  val += "1111";break;
		}
	}
	return val;
}

//2进制转16进制
function tostring16(str)
{
	var a = Number.parseInt(str,2).toString(16);
	return a.toUpperCase();
}

 

逻辑运算代码:(与、或、非、异或以及需要用到的循环左移和文本框判断函数)

//逻辑与运算   同1取1,其余取0
function luojiyu(str1,str2)   //输入字符串
{
	var a = str1.split('');     //将字符串str1转换为数组
	var b = str2.split('');    //将字符串str2转换为数组
	var str = [];
	for(var i =0;i<a.length;i++)
	{
		if(a[i]=="1" && b[i]=="1")
		{
			str[i]="1";
		}
		else
		{
			str[i]="0";
		}

	}
	return str.join('');   //输出二进制字符串
}

//逻辑或运算,同0取0,其余为1
function luojihuo(str1,str2)
{
	var a = str1.split('');     //将字符串str1转换为数组
	var b = str2.split('');    //将字符串str2转换为数组
	var str = [];
	for(var i =0;i<a.length;i++)
	{
		if(a[i]=="0" && b[i]=="0")
		{
			str[i]="0";
		}
		else
		{
			str[i]="1";
		}

	}
	return str.join('');    //输出二进制字符串
}

//逻辑非
function luojifei(str1)
{
	var a = str1.split('');     //将字符串str1转换为数组
	var str = [];
	for(var i=0;i<a.length;i++)
	{
		if(a[i]=="1")
		{
			str[i]="0";
		}
		else
		{
			str[i]="1";
		}
	}
	return str.join('');    //输出二进制字符串
}

//异或运算
function yihuo(str1,str2)
{
	var a = str1.split('');     //将字符串str1转换为数组
	var b = str2.split('');    //将字符串str2转换为数组
	var str = [];
	for(var i =0;i<a.length;i++)     //循环按位异或,相同为0,不同为1
	{
		if(a[i]=="1" && b[i]=="1")
		{
			str[i]="0";
		}
		else if(a[i]=="1" && b[i]=="0")
		{
			str[i]="1";
		}
		else if(a[i]=="0" && b[i]=="1")
		{
			str[i]="1";
		}
		else if(a[i]=="0" && b[i]=="0")
		{
			str[i]="0";
		}

	}
	return str.join('');    //输出二进制字符串
}


//循环左移
function shiftLeft(str, n) {
    var len = str.length;
    // 因为是循环移动,所以需要处理移动位数大于字符串长度的情况
    n = n % len;
    return str.slice(n, len) + str.slice(0, n);   //数组元素左移输出
}

//判断文本框是否为空
function kong(a)
{
	var b = ["A","B","C","D","M","S","T"];  //建立文本框提示数组
			for(var i=1; i<8; i++)         //循环判断文本框是否为空
			{
				var a = document.getElementById("shu_"+[i]).value;  //获取当前ID的文本框的数据
				if(a =="")               //判断内容是否为空,为空就返回false,并终止程序,不为空就返回true
				{
					alert("请输入数据" + b[i-1]);
					return false;
				}
			}
			return true;
}

 

第一次写这玩意儿,如果大家有什么好的改进建议,可以给我留言。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值