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 相关文章推荐
屏蔽网页右键复制和ctrl+c复制的js代码
Jan 04 Javascript
巧用jquery解决下拉菜单被Div遮挡的相关问题
Feb 13 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
Mar 04 Javascript
js实现索引图片切换效果
Nov 21 Javascript
原生Javascript和jQuery做轮播图简单例子
Oct 11 Javascript
react-redux中connect的装饰器用法@connect详解
Jan 13 Javascript
js中的闭包学习心得
Feb 06 Javascript
用Node编写RESTful API接口的示例代码
Jul 04 Javascript
vue 登录滑动验证实现代码
Aug 24 Javascript
微信小程序云开发使用方法新手初体验
May 16 Javascript
JS猜数字游戏实例讲解
Jun 30 Javascript
jQuery+ajax实现文件上传功能
Dec 22 jQuery
利用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
php将时间差转换为字符串提示
2011/09/07 PHP
采用thinkphp自带方法生成静态html文件详解
2014/06/13 PHP
微信API接口大全
2015/04/15 PHP
PHP读书笔记_运算符详解
2016/07/01 PHP
Yii2实现让关联字段支持搜索功能的方法
2016/08/10 PHP
JQuery 动态扩展对象之另类视角
2010/05/25 Javascript
js word表格动态添加代码
2010/06/07 Javascript
一个基于jquery的图片切换效果
2010/07/06 Javascript
jquery 操作iframe的几种方法总结
2013/12/13 Javascript
jQuery修改CSS伪元素属性的方法
2014/07/30 Javascript
Nodejs初级阶段之express
2015/11/23 NodeJs
JavaScript原生对象常用方法总结(推荐)
2016/05/13 Javascript
Bootstrap响应式侧边栏改进版
2016/09/17 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
2017/07/21 Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
2017/08/03 Javascript
浅谈Node.js 沙箱环境
2018/05/15 Javascript
详解vue axios二次封装
2018/07/22 Javascript
vue axios基于常见业务场景的二次封装的实现
2018/09/21 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
2021/03/01 Vue.js
[02:46]解说DC:感谢430陪伴我们的DOTA2国际邀请赛岁月
2016/06/29 DOTA
对numpy中array和asarray的区别详解
2018/04/17 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
Python爬虫小技巧之伪造随机的User-Agent
2018/09/13 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
2018/10/15 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
python 安装库几种方法之cmd,anaconda,pycharm详解
2020/04/08 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
如何基于Django实现上下文章跳转
2020/09/16 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
特步官方商城:Xtep
2017/03/21 全球购物
GC是什么?为什么要有GC?
2013/12/08 面试题
生产现场工艺工程师岗位职责
2013/11/28 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
2015年党风建设工作总结
2015/04/29 职场文书
六五普法心得体会2016
2016/01/21 职场文书