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 相关文章推荐
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
ExtJS Store的数据访问与更新问题
Apr 28 Javascript
javascript 面向对象的JavaScript类
May 04 Javascript
纯js写的分页表格数据为json串
Feb 18 Javascript
对js关键字命名的疑问介绍
Apr 25 Javascript
详细讲解JavaScript中的this绑定
Oct 10 Javascript
react native带索引的城市列表组件的实例代码
Aug 08 Javascript
JavaScript实现单英文金山打字通
Jul 24 Javascript
javascript异常处理实现原理详解
Feb 17 Javascript
jQuery实现日历效果
Sep 11 jQuery
前端vue如何使用高德地图
Nov 05 Javascript
QT与javascript交互数据的实现
May 26 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
ninety plus是什么?ninety plus咖啡好吗?
2021/03/04 新手入门
php HandlerSocket的使用
2011/05/02 PHP
php简单的会话类代码
2011/08/08 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
2018/05/25 PHP
PHP中$GLOBALS与global的区别详解
2019/03/21 PHP
thinkPHP事务操作简单案例分析
2019/10/17 PHP
javascript实现的在当前窗口中漂浮框的代码
2010/03/15 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
2012/02/27 Javascript
JavaScript 操作table,可以新增行和列并且隔一行换背景色代码分享
2013/07/05 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
浅谈Javascript数组的使用
2015/07/29 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
Ajax 加载数据 练习代码
2017/01/05 Javascript
使用JavaScript开发跨平台的桌面应用详解
2017/07/27 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
详解vue中使用vue-quill-editor富文本小结(图片上传)
2019/04/24 Javascript
利用Python的Django框架生成PDF文件的教程
2015/07/22 Python
Django 导出 Excel 代码的实例详解
2017/08/11 Python
python实现动态创建类的方法分析
2019/06/25 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
一套Java笔试题
2016/08/20 面试题
数学专业毕业生自荐信
2013/11/10 职场文书
汽车维修与检测专业应届生求职信
2013/11/12 职场文书
小班幼儿评语大全
2014/04/30 职场文书
餐厅周年庆活动方案
2014/08/25 职场文书
创先争优承诺书
2015/01/20 职场文书
2019年大学毕业生个人自我鉴定范文大全
2019/03/21 职场文书
HR必备:超全面的薪酬待遇管理方案!
2019/07/12 职场文书
浅谈怎么给Python添加类型标注
2021/06/08 Python
一文搞懂python异常处理、模块与包
2021/06/26 Python
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫
联想win10摄像头打不开怎么办?win10笔记本摄像头打不开解决办法
2022/04/08 数码科技
宝塔更新Python及Flask项目的部署
2022/04/11 Python