美文网首页
JS实现PlayFair算法-密码学

JS实现PlayFair算法-密码学

作者: sunningcarry | 来源:发表于2017-03-01 21:34 被阅读211次

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

    相关文章

      网友评论

          本文标题:JS实现PlayFair算法-密码学

          本文链接:https://www.haomeiwen.com/subject/aamcgttx.html