JS实现PlayFair算法-密码学
2017-03-01 本文已影响211人
sunningcarry
Playfair密码(英文:Playfair cipher 或 Playfair square)是一种替换密码,1854年由查尔斯·惠斯通(Charles Wheatstone)的英国人发明。经莱昂·普莱费尔提倡在英国军地和政府使用。
PlayFair算法是古典密码学中的多表代替算法。
PlayFair算法分以下几步:
1:将给出的密钥去重与26个字母拼接成后,生成5X5的矩阵也称作密码表(矩阵中I和J位置相同)
2:将明文两个两个为一对儿
3:利用加密方法来将明文加密
加密方法
P1、P2同行:
对应的C1和C2分别是紧靠P1、P2右端的字母。其中第一列被看作是最后一列的右方。(解密时反向)
P1、P2同列:
对应的C1和C2分别是紧靠P1、P2下方的字母。其中第一行看作是最后一行的下方。(解密时反向)
P1、P2不同行、不同列:
C1和C2是由P1和P2确定的矩形的其它两角的字母,并且C1和P1、C2和P2同行。(解密时处理方法相同)
P1=P2:
则插入一个字母于重复字母之间,并用前述方法处理
若明文字母数为奇数时:
则在明文的末端添加某个事先约定的字母作为填充
举例说明
Paste_Image.png这是demo,可以点击
demo
实验代码
JS
var skid = document.getElementById("secretKey");
var secretKey = ' ';
var arr = new Array();//拆分密钥字符串
var sk = new Array();
var keyTable = new Array();
var ekid = document.getElementById("expressWords");
var expressKey = ekid.value
var arrEK = new Array();
var secretWords = new Array();
/*
第一步:定义密钥一维数组,并将密钥去重
*/
//去重函数
Array.prototype.unique = function()
{
var n = {},r=[]; //n为键值对集合,r为临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
if (!n[this[i]]) //如果表中没有当前项
{
n[this[i]] = true; //存入表
r.push(this[i]); //把当前数组的当前项push到临时数组里面
//console.log(n);
sk.push(this[i]);
}
}
return r;
}
/*
第二步,创建密码表,用去重后的密钥和26个英文字母创建
*/
function createKey(sk){
//字母顺序数组
var allChars = ['A','B','C','D','E','F','G','H','I'||'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
//删除去重后的密钥在26字母中的值
for(var i = 0 ;i<sk.length;i++){
var index = allChars.indexOf(sk[i]);
if (index > -1) {
allChars.splice(index, 1);
}
}
//将未出现过的26个字母与去重密钥合并成密码表一维数组
allChars = sk.concat(allChars);
//将一维数组转成二维
for(var i = 0 ; i<5 ; i++){
keyTable[i] = new Array();
for(var j = 0;j<5;j++){
keyTable[i][j] = allChars[i*5+j];
}
}
// console.log('keyTablellll:'+keyTable[3][3]);
}
/*
第三步:处理明文 ,将明文两个两个为一对,并且将明文中的J换成I
*/
function produceExpress(e){
//console.log('e:'+e);
var arr = e.split('');
if(arr.length%2==0){
for(var i=0 ; i<arr.length;i++){
if(arr[i] == 'J'){
arr[i] = 'I';
}
}
for(var i=0 ; i<arr.length;i++){
arrEK.push([arr[i],arr[i+1]]);
i = i+1;
}
}else{
arrEK.push('X');
}
for(var i = 0;i<7;i++){
console.log('arrEKllll:'+arrEK[i]);
}
}
/*
第四步:利用playfair算法,求出密文
*/
function getSecret(a,b){
//a为密码表
//b为分组后的明文
var secretTable = [];
var express = [];
secretTable = a;
express = b;
var p1,p2,c1,c2;
var row1,col1,row2,col2;
for(var k =0;k<express.length;k++){
for(var i = 0;i<secretTable.length;i++){
for(var j=0;j<secretTable[i].length;j++){
if(express[k][0] == secretTable[i][j]){
row1=i;
col1=j;
}
if(express[k][1] == secretTable[i][j]){
row2=i;
col2=j;
}
}
}
if(row1 == row2){
secretWords.push(secretTable[row1][(col1+1)%5]);
secretWords.push(secretTable[row1][(col2+1)%5])
}else if (col1 == col2){
secretWords.push(secretTable[(row1+1)%5][col1]);
secretWords.push(secretTable[(row2+1)%5][col1]);
}else{
//不同行不同列
secretWords.push(secretTable[row1][col2]);
secretWords.push(secretTable[row2][col1]);
}
}
}
function main(){
var a = document.getElementById('secretWords');
var btn = document.getElementById('button');
btn.addEventListener('click',function(){
//a.value = secretWords.toString();
if(skid.value!= ' '){
secretKey = skid.value.toUpperCase();
arr = secretKey.split('');
}
if(ekid.value!= ' '){
expressKey = ekid.value.toUpperCase();
}
arr.unique();
console.log('quchonghou:'+sk);
//创建密码表为keyTable
createKey(sk);
console.log('-----------------------------');
for(var i = 0;i<5;i++){
console.log('keyTable:'+keyTable[i]);
}
console.log('-----------------------------');
//处理明文后为arrEK
produceExpress(expressKey);
console.log('mingwen:'+arrEK);
//求密文secretWords
getSecret(keyTable,arrEK);
console.log('secretWords:'+secretWords);
a.value = secretWords.toString();
});
}
main();
html
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>playfair加密算法</title>
<style>
body{
font-family: 'Open Sans', sans-serif;
font-size: 20px;
line-height: 1.42857143;
color: #fff;
background-color: #F39D7C;
}
#container{
width: 500px;
height: 500px;
margin:0 auto;
background-color: #2A1106;
border-radius: 50px;
margin-top:100px;
box-shadow: 0 0 15px #F13006;
}
#container{
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
input{
width: 200px;
height: 30px;
}
#button{
width: 80px;
height: 35px;
background: #ef9a79;
font-size: 15px;
border:none;
border-radius: 3px;
}
#button:hover{
background: #f47c20;
}
</style>
</head>
<body>
<!-- top-start -->
<div id="container">
<h1>playFair加密算法</h1>
<span>输入密钥:</span><input type="text" id="secretKey" name="secretKey" value="">
<span>输入明文:</span>
<input type="text" id="expressWords" name="expressWords" value="">
<span>输出密文:</span>
<input type="text" id="secretWords" name="secretWords"value="">
<button id ="button" type="submit" >加密</button>
<p id="demo"></p>
</div>
<script src="first.js" >
</script>
</body>
</html>
希望有更多小胖友提出宝贵意见,若有关于前端的问题,或者关于大学方面的感想可以私聊我(~):
github
知乎
简书
个人博客
微博