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
知乎
简书
个人博客
微博

上一篇下一篇

猜你喜欢

热点阅读