#维吉尼亚(Vigenère)密码的加密和解密以及方阵(js版)
《信息安全》这门课这一周才刚刚开课,真正的学习加密解密也是近几天的事,本来研究古典加密也只是一时兴起,但是现在这件事由旁门左道变成正事了……
很抱歉的是,以上并不是我写此程序的原因……话说就在前天,有一同学给我发了一条短信,短信内容是——什么来着?抱歉,原短信已经被我从手机上HX了,因为这条短信真正被我解密之后发现了一些错误,很不HX。不过大家不要担心,被我修改了一些错误之后的短信内容是这样的:“Dxsokate xprfznj efqtf hiebbr Uckggxwzi ctfhmq!”。很明显,加密了,不得不佩服此同学的活学活用呀~大家鼓掌表扬一下~
比较不好玩的是本人对他发的信息并不感冒,我是绝对不会以大量的运算的代价去破译他的密码的,即便是我有如此高超的破译水平。不过再次值得表扬的是这位童鞋很有自知之明,不久之后就又把密钥发给我了,内容是“rpfirst”(关于他为什么用这个密钥,其实源自本人对RP的重视程度)。他的意思很明显,那条短信是以密钥“rpfirst”加密的维吉尼亚密文(因为其他的密文估计他手动加密不太可能,况且我们还没学这么先进的加密方式)
不过再次遗憾的是,本人懒得很,不愿意手动的进行解密,尽管密钥都告诉我了……直到昨天早上,此信息已经丧失时效性,我依然没有对此信息进行解密,然后再到昨天下午,我决定写一个维吉尼亚密文的加密和解密程序。
最终,我让计算机将此密文成功解密(解密结果见程序) 。
事实证明,是懒人创造了这个世界……
闲话少讲,上代码
```HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<meta http-equiv="author" content="yimengqiannian" />
<meta http-equiv="keywords" content="vigenere 维吉尼亚 密码 方阵 加密 解密" />
<meta http-equiv="Page-Enter" content="revealTrans(Duration=2,Transition=23)">
<meta http-equiv="Page-Exit" content="revealTrans(Duration=2,Transition=23)">
<title>维吉尼亚(Vigenère)密码 </title>
<style>
body{
font-size:18px;
font-family:"楷体_GB2312", "仿宋_GB2312";
}
caption{
text-align:center;
font-size:20px;
font-weight:bold;
}
center{
font-size:28px;
font-weight:bold;
}
.matrix{
border:#BBBBFF solid thick;
cursor:pointer;
}
.matrix td{
width:18px;
height:18px;
border:#aaccaa 1px solid;
text-align:center;
}
.matrix th{
width:18px;
height:18px;
border:#DDDDFF 1px solid;
background-color:#EEEEFF;
text-align:center;
}
.cal{
padding:20px 20px 20px 20px;
}
.cal td,th{
border-width:0px;
}
</style>
</head>
<script language="<a href="http://lib.csdn.net/base/javascript" class='replace_word' title="JavaScript知识库" target='_blank' style='color:#df3434; font-weight:bold;'>JavaScript</a>">
//-----------声明全局变量--------------
var AU="A".charCodeAt(0);//大写A的编码
var AL="a".charCodeAt(0);//小写a的编码
var ZU="Z".charCodeAt(0);//大写Z的编码
var ZL="z".charCodeAt(0);//小写z的编码
var col1,col2;//方阵的列
//--------------方阵函数---------
function writeThead(){//方阵表头部
document.writeln("<thead><tr><th> </th>");
for(var i=0;i<26;i++){
document.writeln("<th>"+String.fromCharCode(AU+i)+"</th>");
}
document.writeln("</tr></thead>");
}
function forTo(i,j){//向前映射
return (i+j)%26;
}
function backTo(i,j){//向后映射
return (i+26-j)%26;
}
function writeTbody(fun,id){//方阵体,传入映射函数和表编号
//document.writeln("<colgroup span='26'>");
for(var i=0;i<=26;i++){
document.writeln("<col/>");
}
//document.writeln("</colgroup>");
document.writeln("<tbody>");
for(var i=0;i<26;i++){
document.writeln("<tr onmouseover='this.style.backgroundColor=/"#DDDDff/"' onmouseout='this.style.backgroundColor=/"/"'>");
document.writeln("<th>"+String.fromCharCode(AU+i)+"</th>");
for(var j=0;j<26;j++){
document.writeln("<td onmouseover='pointIn("+j+",col"+id+")' onmouseout='pointOut("+j+",col"+id+")'>"+String.fromCharCode(AU+fun(i,j))+"</td>");
}
document.writeln("</tr>");
}
document.writeln("</tbody>");
}
function initCols(){//初始化列向量
col1=document.getElementById("matrix1").getElementsByTagName("col");
col2=document.getElementById("matrix2").getElementsByTagName("col");
}
function pointIn(j,cols){//鼠标处于j列时修改此列颜色
cols[j+1].style.backgroundColor="#DDDDFF";
}
function pointOut(j,cols){//鼠标移出j列时恢复此列颜色
cols[j+1].style.backgroundColor="";
}
//------------------加密解密函数-----------
function isUpLetter(c){//判断是否为大写字符编码
if(c>=AU&&c<=ZU)return true;
else return false;
}
function isLowLetter(c){//判断是否为小写字符编码
if(c>=AL&&c<=ZL)return true;
else return false;
}
function isLetter(c){//判断是否为英文字符编码
return isUpLetter(c)||isLowLetter(c);
}
function isLetterStr(s){//判断是否为英文字符串
for(var i=0;i<s.length;i++){
if(!isLetter(s.charCodeAt(i)))
return false;
}
return true;
}
function jiami(){//加密函数
var key=document.form1.miyao.value.toLowerCase();
if(!isLetterStr(key)){
alert("密钥必须为全英文字符串!");
document.form1.miyao.focus();
return false;
}
var express= document.form1.mingwen.value;
var secret="";
if(key.length==0)secret=express;
else{
var A;
var ee;
for(var i=0;i<express.length;i++){
ee=express.charCodeAt(i);
if(isUpLetter(ee))A=AU;
else if(isLowLetter(ee))A=AL;
else{
secret+=express.charAt(i);
continue;
}
secret+=String.fromCharCode(A+((ee-A)+(key.charCodeAt(i%key.length))-AL)%26);
}
}
document.form1.miwen.value=secret;
}
function jiemi(){//解密函数
var key=document.form1.miyao.value.toLowerCase();
if(!isLetterStr(key)){
alert("密钥必须为全英文字符串!");
document.form1.miyao.focus();
return false;
}
var secret= document.form1.miwen.value;
var express="";
if(key.length==0)express=secret;
else{
var A;
var se;
for(var i=0;i<secret.length;i++){
se=secret.charCodeAt(i);
if(isUpLetter(se))A=AU;
else if(isLowLetter(se))A=AL;
else{
express+=secret.charAt(i);
continue;
}
express+=String.fromCharCode(A+((se-A)+26-(key.charCodeAt(i%key.length)-AL))%26);
}
}
document.form1.mingwen.value=express;
}
</script>
<body onload="initCols()">
<center>维吉尼亚(Vigenère)密码</center>
<form name="form1">
<table class="cal" width="70%" border="5" align="center" cellpadding="0" cellspacing="0">
<caption>维吉尼亚(Vigenère)密码加密与解密</caption>
<tr>
<td colspan="3" align="center">密钥:
<input name="miyao" type="text" size="100" value="rpfirst"/>
</td>
</tr>
<tr>
<td width="0%">
明文: <br/>
<textarea name="mingwen" cols="50" rows="10">Mingtian shangwu woyao canjia Putonghua kaoshi!</textarea></td>
<td width="0%">
<input name="button" type="button" value="加密>>" onclick="jiami()" />
<br/>
<input type="button" name="Submit2" value="<<解密" onclick="jiemi()" /> </td>
<td width="0%">
密文:<br/>
<textarea name="miwen" cols="50" rows="10">Dxsokate xprfznj efqtf hiebbr Uckggxwzi ctfhmq!</textarea></td>
</tr>
</table>
</form>
<br/>
<table border="0" align="center">
<tr>
<td>
<table id="matrix1" class="matrix" cellpadding="0" cellspacing="0" align="center">
<caption>
加密方阵<br/>
密钥(行/列)+明文(列/行)=密文
</caption>
<script language="javascript">
writeThead();
writeTbody(forTo,1);
</script>
</table>
</td>
<td>
<table id="matrix2" class="matrix" cellpadding="0" cellspacing="0" align="center">
<caption>解密方阵<br/>
密文(行)-密钥(列)=明文
</caption>
<script language="javascript">
writeThead();
writeTbody(backTo,2);
</script>
</table>
</td>
</tr>
</table>
</body>
</html>
```
##说明:
- **使用方式:**(非 NC者可以54):将分割线内的代码(不包括分割线)粘贴到记事本里,另存为*.html格式,用浏览器打开。
- **兼容性:**分别在 IE6.0,FireFox3.6.3,Google Chrome 4.1测试,IE和FireFox效果良好,但是由于Chrome对于非兼容标签<col>的兼容性不好,所以在Chrome中鼠标指向方阵的某一格时,当前列不会高亮显示,其他方面效果良好。故此程序的推荐运行浏览器为FireFox。
- **其他:**对于此程序中涉及的当前列高亮显示的兼容办法,还望各位大牛帮忙解决。再关于程序其中的错误以及各位大侠有什么比较好的优化,也欢迎大家多加指点。
- **运行结果:**
![运行结果](demo.png "运行结果")