JavaScript实现维吉尼亚(Vigenere)密码算法实例


Posted in Javascript onNovember 22, 2013

传统加密技术对于当今的网络安全发挥不了大作用,但每一本讲述密码学的书的开头都会率先介绍它们,因为它们是密码学的基础,是密码学的历史。几乎每一本密码学的书在讲述Vigenere密码的章节都会有这么一个《Vigenere代换表》用户讲解Vigenere密码机制:

JavaScript实现维吉尼亚(Vigenere)密码算法实例

加密过程很简单,就是给定密钥字母x和明文字母y,密文字母是位于x行和y列的那个字母。这样就决定了加密一条消息需要与消息一样长的密钥字符串,通常,密钥字符串是密钥词的重复。
以《密码编码学与网络安全——原理与实践》中的例子来作为本文的例子。比如密钥词是deceptive,消息是“we are discovered save yourself”,那么加密过程如下:

deceptivedeceptivedeceptive(密钥字符串)
wearediscoveredsaveyourself(消息)
ZICVTWQNGRZGVTWAVZHCQYGLMGJ(密文)

密文中的第一个字母“Z”是怎么得来的?从Vigenere代换表中,以密钥字符串中的“d”为行,消息中的“w”为列的那个字母就是“Z”了。

使用查表的方式多加密几次就能很轻易地总结出规律:将A~Z以0~25编号,那么加密过程就是,在代换表的第一行中找到消息字母,如“w”,然后向后移动d(即3)次,所得的字母就是密文了。如果数到末位,那么下一次移位就从头(即A)继续。 也就是说,可以将A~Z看成一个环,加密过程就是找定消息字母后,将指针往环的某个特定方向移位,次数就是密钥字母所代表的数字。这其实是一个模26的过程。
扩展一下,以上加密仅能对26个字母进行加密,而且不能区分大小写。但其实英文中除了字母外,还有标点符号,还有空格。如果考虑到大部分英文字符,那么Vigenere代换表将比较大,而且有点浪费空间的嫌疑。如果假设能被加密的字符有N个,如果把这N个字符建成一个环,那么加密过程就是模N的过程,即,C(i)=(K(i)+P(i))modN,其中K、C、P分别代表的是密钥空间、密文空间、消息(明文)空间。
网络上有人用C实现了这个加密算法,几乎都是使用查代换表的方法。虽然可以程序生成代换表,但所生成的代换表太有规律了。以下我用Javascript实现了一次,使用的是模的方法,感觉灵活度更大,占用的空间肯定也更小(时间效率尚未估计)

var Vigenere = {
    _strCpr: 'abcdefghijklmnopqrstuvwxyz_12345 67890.ABCDEFGHIJKLMNOPQRSTUVWXYZ',//可以将此字符串的顺序打乱点,或者添加更多字符
    _strKey: function(strK,str){//生成密钥字符串,strK为密钥,str为明文或者密文
        var lenStrK = strK.length;
        var lenStr = str.length;
        if(lenStrK != lenStr){//如果密钥长度与str不同,则需要生成密钥字符串
            if(lenStrK < lenStr){//如果密钥长度比str短,则以不断重复密钥的方式生成密钥字符串
                while(lenStrK < lenStr){
                    strK = strK + strK;
                    lenStrK = 2 * lenStrK;
                }
            }//此时,密钥字符串的长度大于或等于str长度
            strK = strK.substring(0,lenStr);//将密钥字符串截取为与str等长的字符串
        }
        return strK;
    }
}
Vigenere.lenCpr = Vigenere._strCpr.length;
Vigenere.Encrypt = function(K,P){//加密算法,K为密钥,P为明文
    K = Vigenere._strKey(K,P);
    var lenK = K.length;
    var rlt = '';
    var loop = 0;
    for(loop=0; loop<lenK; loop++){
        var iP = Vigenere._strCpr.indexOf(P.charAt(loop));
        if(iP==-1) return '本算法暂时不能对字符:' + P.charAt(loop) + '进行加密';
        var iK = Vigenere._strCpr.indexOf(K.charAt(loop));
        if(iK==-1) return '密钥中包含非法字符:' + K.charAt(loop);
        var i = (iP + iK) % Vigenere.lenCpr;
        rlt = rlt + Vigenere._strCpr.charAt(i);
    }
    return rlt;    
};
Vigenere.DisEncrypt = function(K,C){
    K = Vigenere._strKey(K,C);
    var lenK = K.length;
    var rlt = '';
    var loop = 0;
    for(loop=0; loop<lenK; loop++){
        var iK = Vigenere._strCpr.indexOf(K.charAt(loop));
        if(iK==-1) return '密钥中包含非法字符:' + K.charAt(loop);        
        var iC = Vigenere._strCpr.indexOf(C.charAt(loop));
        if(iK > iC){
            rlt += Vigenere._strCpr.charAt(iC + Vigenere.lenCpr - iK);
        }
        else{
            rlt += Vigenere._strCpr.charAt(iC - iK);
        }
    }
    return rlt;
};
Javascript 相关文章推荐
取选中的radio的值
Jan 11 Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
Oct 20 Javascript
各浏览器对link标签onload/onreadystatechange事件支持的差异分析
Apr 27 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
Apr 12 Javascript
node.js中的Socket.IO使用实例
Nov 04 Javascript
Javascript数组与字典用法分析
Dec 13 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 Javascript
JavaScript 计算笛卡尔积实例详解
Dec 02 Javascript
Vue 自定义动态组件实例详解
Mar 28 Javascript
vue单页缓存存在的问题及解决方案(小结)
Sep 25 Javascript
傻瓜式vuex语法糖kiss-vuex整理
Dec 21 Javascript
layer.js open 隐藏滚动条的例子
Sep 05 Javascript
利用js判断浏览器类型(是否为IE,Firefox,Opera浏览器)
Nov 22 #Javascript
javascript删除option选项的多种方法总结
Nov 22 #Javascript
js截取固定长度的中英文字符的简单实例
Nov 22 #Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 #Javascript
nodeType属性返回被选节点的节点类型介绍
Nov 22 #Javascript
在Iframe中获取父窗口中表单的值(示例代码)
Nov 22 #Javascript
解析URI与URL之间的区别与联系
Nov 22 #Javascript
You might like
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
基于jquery的has()方法以及与find()方法以及filter()方法的区别详解
2013/04/26 Javascript
JS获取select的value和text值的简单实例
2014/02/26 Javascript
JS实现鼠标单击与双击事件共存
2014/03/08 Javascript
自写的jQuery异步加载数据添加事件
2014/05/15 Javascript
javascript实现点击提交按钮后显示loading的方法
2015/07/03 Javascript
js点击文本框后才加载验证码实例代码
2015/10/20 Javascript
AngularJS 中的指令实践开发指南(一)
2016/03/20 Javascript
bootstrap flask登录页面编写实例
2016/11/01 Javascript
BetterScroll 在移动端滚动场景的应用
2017/09/18 Javascript
JavaScript实现音乐自动切换和轮播
2017/11/05 Javascript
通过webpack引入第三方库的方法
2018/07/20 Javascript
Vue中插入HTML代码的方法
2018/09/21 Javascript
小程序视频或音频自定义可拖拽进度条的示例代码
2018/09/30 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
react quill中图片上传由默认转成base64改成上传到服务器的方法
2019/10/30 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
[45:52]2018DOTA2亚洲邀请赛 4.1小组赛 A组加赛 LGD vs Liquid
2018/04/02 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
Python中几个比较常见的名词解释
2015/07/04 Python
python中abs&amp;map&amp;reduce简介
2018/02/20 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
Python何时应该使用Lambda函数
2019/07/02 Python
python实现两个经纬度点之间的距离和方位角的方法
2019/07/05 Python
python集合能干吗
2020/07/19 Python
浅析HTML5页面元素及属性
2021/01/20 HTML / CSS
Molly Bracken法国电子商店:法国女性时尚品牌
2019/07/24 全球购物
介绍一下代理模式(Proxy)
2014/10/17 面试题
高中军训感言400字
2014/02/24 职场文书
法定代表人授权委托书
2014/09/19 职场文书
认真学习保证书
2015/02/26 职场文书
教学督导岗位职责
2015/04/10 职场文书
简单的辞职信范文(2016最新版)
2015/05/12 职场文书
2016先进集体事迹材料范文
2016/02/25 职场文书
深入解析MySQL索引数据结构
2021/10/16 MySQL