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基础,拓宽知识面。这条路任重道远。

(0)

相关推荐

  • js交换排序 冒泡排序算法(Javascript版)

    比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 针对所有的元素重复以上的步骤,除了最后一个. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较. function sort(elements){ for(var i=0;i<elements.length-1;i++){ for(var j=0;j<elements.length-i-1;j++){ if(elemen

  • JavaScript实现twitter puddles算法实例

    今天发现了一个挺好玩的算法题,下面是它的算法描述,源自twitter的一道面试题. twitter puddles 算法描述 先看一副图 上图里的数字是根据一个数组内容来描述的,最后会根据每个数字的大小来模拟一道墙的高度,最后生成一面墙,问你,当下雨的时候,这面墙可以装多少水,以1为计数单位. 下面是装完水之后的一面墙的样子 看完上面上幅图,感觉是不是很好玩,确实,下面来简单的分析下它的算法实现 其实这个原理比较简单,总共有下面几个要点: 1.最左边和最右边肯定不能装水 2.装水的高度依赖自身左

  • JavaScript blog式日历控件新算法

    使用说明: 程序比较简单,代码中都有说明,这里说说怎么使用. 首先是实例化一个Calendar,并设置参数. 参数说明: Year:要显示的年份 Month:要显示的月份 SelectDay:选择日期 onSelectDay:在选择日期触发 onToday:在当天日期触发 onFinish:日历画完后触发 一般SelectDay设置成选择了的日期,并在onSelectDay中设置一个函数用来设置这个日期的样式, 例如实例里SelectDay设置成今个月10号并在那天样式设为onSelect: 复

  • javascript &&和||运算法的另类使用技巧

    &&和||在JQuery源代码内尤为使用广泛,由于本人没有系统的学习js,所以只能粗略的自我理解出来,希望大家指点下. 粗略理解如下: a() && b() :如果执行a()后返回true,则执行b()并返回b的值:如果执行a()后返回false,则整个表达式返回a()的值,b()不执行: a() || b() :如果执行a()后返回true,则整个表达式返回a()的值,b()不执行:如果执行a()后返回false,则执行b()并返回b()的值: && 优先

  • 一个简单的JavaScript 日期计算算法

    复制代码 代码如下: <script type="text/javascript"> var today=new Date(); //定义当天日期对象 var year = today.getYear(); //获取年份 var month = today.getMonth(); //获取月份 var date = today.getDate(); //获取日期值 try{ //定义下个日期对象,日期值加上30天 var nextDay = new Date(year,mo

  • Javascript中的常见排序算法

    具体代码及比较如下所示: 复制代码 代码如下: <!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" lang="gb2312">

  • JavaScript生成GUID的多种算法小结

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度为128位的数字标识符.GUID 的格式为"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",其中的 x 是 0-9 或 a-f 范围内的一个32位十六进制数.在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID. GUID 的总数达到了2^128(3

  • Javascript和HTML5利用canvas构建Web五子棋游戏实现算法

    这只是一个简单的JAVAscript和HTML5小程序,没有实现人机对战. 五子棋棋盘落子点对应的二维数组.数组的元素对应落子点.比如数组元素值为0表示该元素对应的落子点没有棋子,数组元素值为1表示该元素对应的落子点有白棋子,数组元素值为2表示该元素对应的落子点有黑棋子: 判断五子棋赢棋的算法是通过对五子棋棋盘落子点对应的二维数组的操作来实现的. 判断五子棋赢棋算法 下边的函数可以实现判断五子棋赢棋的算法,也可以按照教材中相应的算法实现. 其中函数的参数xx.yy为数组下标,chess数组实现五

  • javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号

    具体题目是这样的: 从1--9中选取N个数字,组成不重复的N位数,从小到大进行编号,当输入其中任何一个数M时,能找出该数字对应 的编号.如 N=3,M=213. 输出:[123(1) , 132(2) , 213(3) , 231(4) , 312(5) , 321(6)]--->X=2 首先看到题目想到的是生成一个从少到大的全排列的数组,然后再遍历数组得到对应的序号(数组下标加1),又或者想到一个个从小到大的生成push进数组,然后判断该数是不是当前题目给的数,如果是的话要求的序号就是当前数组

  • javascript图片相似度算法实现 js实现直方图和向量算法

    复制代码 代码如下: function getHistogram(imageData) {    var arr = [];    for (var i = 0; i < 64; i++) {        arr[i] = 0;    }    var data = imageData.data;    var pow4 = Math.pow(4, 2);    for (var i = 0, len = data.length; i < len; i += 4) {        var

随机推荐