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 相关文章推荐
初窥JQuery-Jquery简介 入门了解篇
Nov 25 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
Aug 08 Javascript
jquery $.each() 使用小探
Aug 23 Javascript
jquery等宽输出文字插件使用介绍
Sep 18 Javascript
使用JS读秒使用示例
Sep 21 Javascript
JavaScript中连接操作Oracle数据库实例
Apr 02 Javascript
jQuery获取上传文件的名称的正则表达式
May 21 Javascript
javascript中FOREACH数组方法使用示例
Mar 01 Javascript
使用grunt合并压缩js和css文件的方法
Mar 02 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
May 18 Javascript
vant 解决tab切换插件标题样式自定义的问题
Nov 13 Javascript
Echarts如何重新渲染实例详解
May 30 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
ThinkPHP3.1新特性之对分组支持的改进与完善概述
2014/06/19 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
php判断是否为ajax请求的方法
2016/11/29 PHP
JQuery实现点击div以外的位置隐藏该div窗口
2013/09/13 Javascript
js切换光标示例代码
2013/10/10 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
在Ubuntu上安装最新版本的Node.js
2014/07/14 Javascript
纯JS实现可拖拽表单的简单实例
2016/09/02 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
vue.js 上传图片实例代码
2017/06/22 Javascript
深入剖析Express cookie-parser中间件实现示例
2018/02/01 Javascript
vue中如何使用ztree
2018/02/06 Javascript
浅谈微信页面入口文件被缓存解决方案
2018/09/29 Javascript
node中实现删除目录的几种方法
2019/06/24 Javascript
微信小程序如何获取群聊的openGid以及名称详解
2019/07/17 Javascript
[02:44]DOTA2英雄基础教程 魅惑魔女
2014/01/07 DOTA
[05:34]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY第二弹
2014/06/25 DOTA
python根据日期返回星期几的方法
2015/07/06 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
python脚本开机自启的实现方法
2019/06/28 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
2019/07/19 Python
解决python调用自己文件函数/执行函数找不到包问题
2020/06/01 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
美国男装连锁零售商:Men’s Wearhouse
2016/10/14 全球购物
Myprotein比利时官方网站:欧洲第一运动营养品牌
2020/10/04 全球购物
电子商务专业个人的自我评价
2013/11/19 职场文书
春节活动策划方案
2014/01/24 职场文书
旅游业大学生创业计划书
2014/01/31 职场文书
道德模范先进事迹
2014/02/14 职场文书
社区维稳工作方案
2014/06/06 职场文书
交通志愿者活动总结
2014/06/27 职场文书
“九一八事变纪念日”国旗下讲话稿
2014/09/14 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
Mysql开启外网访问
2022/05/15 MySQL
MySQL导致索引失效的几种情况
2022/06/25 MySQL