• javascript实现playfair和hill密码算法


    时至期末,补习信息安全概论作业。恰巧遇古典密码学算法中的playfair算法和hill算法,用javascript语言实现起来是在有趣,边查百度边编码,顺便好好补习一下javascript基础。

    playfair

    Playfair密码(英文:Playfair cipher 或 Playfair square)是一种替换密码。依据一个5*5的正方形组成的密码表来编写,表中排列有25个字母。对于英语中的26个字母,去掉最常用的Z,构成密码表。

    实现思路:

    1,编制密码表

      密钥是一个单词或词组,密码表则根据用户所给出的密钥整理而出。若有重复字母,可将后面重复的字母去掉。 

    如密钥crazy dog,可编制成
    C
    O
    H
    M
    T
    R
    G
    I
    N
    U
    A
    B
    J
    P
    V
    Y
    E
    K
    Q
    W
    D
    F
    L
    S
    X

     

    /*
    *    功能:编制密码表
    *
    *    参数:密钥(经过去除空格和大写处理)
    *
    *    返回:密码表
    */
    function createKey(keychars){
           //字母顺序数组
        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'];
           //变量keychars获取字母在字母顺序表中位置,删除该字母
        for(var i = 0 ;i<keychars.length;i++){
            var index = allChars.indexOf(keychars[i]);
            if (index > -1) {
                allChars.splice(index, 1);
            }
        }
           //将keychar中的字母插入到字母表中
        for(var i = keychars.length-1;i>=0;i--){
            allChars.unshift(keychars[i]);
        }
            //从第一列将keychars插入至密码表
        for(var i = 0 ; i<5 ; i++){
            for(var j = 0; j<5 ;j++){
                key[j][i] = allChars[i*5+j];
            }
        }
    }    

    考虑将keychars插入到密码表时需要去除重复字符和Z,设计算法如下:

    /*
    *    功能:去除字符串中重复字母
    *
    *    参数:需要进行处理的字符串
    *
    *    返回:处理过的字符串
    */
    function removeDuplicate(str){
        var result = [],tempStr = "";
        var arr = str.split('');//把字符串分割成数组
            //arr.sort();//排序
            for(var i = 0; i < arr.length; i++){
                var repeatBack = true;//设计变量是为确保字符串前部分不存在相同字符,因为以下算法只能确保连在一起相同的字符
                for(var j = 0;j<result.length ;j++){
                    if(arr[i] == result[j])
                        repeatBack = false;
                }
                if(arr[i] !== tempStr && repeatBack){
                    result.push(arr[i]);
                    tempStr = arr[i];
                }else{
                    continue;
                }
            }
            return result.join("");//将数组转换为字符串
    }

    2,整理明文

      将明文每两个字母组成一对。如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X。初期编码时考虑不周到,强硬地拒绝输入字母个数为单数,用户体验不佳。

    var k = document.getElementById("keychars").value.toUpperCase().replace(/s/ig,'');

    对明文去除空格和转换为大写处理。

    3,编写密文

    明文加密规则(出自百度):
     
    1 )若p1 p2在同一行,对应密文c1 c2分别是紧靠p1 p2 右端的字母。其中第一列被看做是最后一列的右方。如,按照前表,ct对应oc
    2 )若p1 p2在同一列,对应密文c1 c2分别是紧靠p1 p2 下方的字母。其中第一行被看做是最后一行的下方。
    3 )若p1 p2不在同一行,不在同一列,则c1 c2是由p1 p2确定的矩形的其他两角的字母(至于横向替换还是纵向替换要事先约好,或自行尝试)。如按照前表,wh对应tk或kt。
     
    如,依照上表,明文where there is life,there is hope.
    可先整理为wh er et he re is li fe th er ei sh op ex
    然后密文为:kt yg wo ok gy nl hj of cm yg kg lm mb wf
    将密文变成大写,然后几个字母一组排列。
    如5个一组就是KTYGW OOKGY NLHJO FCMYG KGLMM BWF
     
    4,解密
    将密钥填写在一个5*5的矩阵中(去出重复字母和字母z),矩阵中其它未用到的字母按顺序填在矩阵剩余位置中,根据替换矩阵由密文得到明文。反其道而行。
     
    实现效果如图:

    hill

    希尔密码(Hill Password)是运用基本矩阵论原理的替换密码。依据一个5*5的正方形组成的密码表来编写,表中排列有25个字母。对于英语中的26个字母,去掉最常用的Z,构成密码表。

    实现思路:

    1,编写字母表
    var chars = ['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'];

    2,随机生成密匙

    /*
    *    功能:随机生成密钥
    *
    *    返回:密匙矩阵
    */
    function randomCreateKey(){
        //随机生成0到26的数字
        for(var i = 0;i<3;i++){
            for(var j = 0;j<3;j++){
                key[i][j] = Math.round(Math.random()*100%26)
            }
        }
    }

    3,关键性代码,根据自动生成的密匙,对明文进行处理:

    /*
    *    功能:hill算法
    *
    *    参数:长度是3的倍数的大写数组
    *    
    *    返回:加密后的字符串
    */
    function hill(p){
        //大写字母密文
        var res = "";
            //制定总共需要对字符串经行遍历的次数
        var round = Math.round(p.length/3);
        //处理
        for(var b = 0;b<round;b++){
            //明文3
                var temp3 ="";
            var tempArr3 = [];
            var sumArr3 = [];
            for(var i = 0;i<3;i++){
                temp3 += p.shift();
                for(var j = 0;j<chars.length;j++){
                    if(temp3[i] == chars[j])
                        tempArr3[i] = j;
                }
            }
                    //计算
            for(var i =0;i<3;i++){
                for(var j = 0;j<3;j++){
                    sumArr3[i] = (tempArr3[j]*key[i][j])%26;
                }
            }
                    //获取字符在字母表中对应索引
            for(var i =0;i<3;i++){
                res += chars[sumArr3[i]];
            }
        }
        return res;
    }; 

     实现效果如图:

    以上算法存在不足:

             1,面向过程设计,耦合度高

             2,过多嵌套循环,算法效率有待优化

             3,对于可能出现的情况考虑不周到,例如没有对用户输入非字母字符时进行处理。

    总结:

    学了一段时间的信息安全概论这门课,只能对信息安全了解皮毛。信息安全是一门很有趣的科目,平时遇到一些问题尽可能多思考,多动手,多运用。同时也要加强数学基础积累,巩固js基础,拓宽知识面。这条路任重道远。

         

  • 相关阅读:
    创建vue项目的时候报错,spawn yarn ENOENT
    理解比特币(4)——实现原理
    比特币(3)——比特币的其他优势
    比特币(2)——最大优势是价值存储
    如何在K8S中优雅的使用私有镜像库 (Docker版)
    [Go] godoc 打开本地文档, windows 同样适用
    [FAQ] Golang error strings should not be capitalized or end with punctuation
    [Go] gorm 错误处理 与 链式/Finisher方法
    [Go] golang 替换组件包 更新 go.mod, go.sum 的方式
    [FAQ] golang-migrate/migrate error: migration failed in line 0: (details: Error 1065: Query was empty)
  • 原文地址:https://www.cnblogs.com/0603ljx/p/4147539.html
Copyright © 2020-2023  润新知