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 相关文章推荐
转换json格式的日期为Javascript对象的函数
Jul 13 Javascript
THREE.JS入门教程(4)创建粒子系统
Jan 24 Javascript
javascript自适应宽度的瀑布流实现思路
Feb 20 Javascript
JavaScript中的prototype和constructor简明总结
Apr 05 Javascript
关于Javascript 对象(object)的prototype
May 09 Javascript
JavaScript实现的内存数据库LokiJS介绍和入门实例
Nov 17 Javascript
js表单元素checked、radio被选中的几种方法(详解)
Aug 22 Javascript
jQuery中的deferred对象和extend方法详解
May 08 jQuery
vue init失败简单解决方法(终极版)
Dec 22 Javascript
Vue加载json文件的方法简单示例
Jan 28 Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 Javascript
js模拟实现烟花特效
Mar 10 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
一个php作的文本留言本的例子(五)
2006/10/09 PHP
php的ajax框架xajax入门与试用介绍
2010/12/19 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
用javascript控制iframe滚动的代码
2007/04/10 Javascript
Mootools 1.2教程 事件处理
2009/09/15 Javascript
最短的IE判断代码
2011/03/13 Javascript
js中onload与onunload的使用示例
2013/08/25 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
2014/04/04 Javascript
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
Javascript 创建类并动态添加属性及方法的简单实现
2016/10/20 Javascript
Vuex之理解Store的用法
2017/04/19 Javascript
将angular-ui的分页组件封装成指令的方法详解
2017/05/10 Javascript
React-router中结合webpack实现按需加载实例
2017/05/25 Javascript
Vue 项目代理设置的优化
2018/04/17 Javascript
JavaScript实现一个带AI的井字棋游戏源码
2018/05/21 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
2018/09/01 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
2019/09/10 Javascript
python笔记(1) 关于我们应不应该继续学习python
2012/10/24 Python
Python的math模块中的常用数学函数整理
2016/02/04 Python
Python正则表达式教程之三:贪婪/非贪婪特性
2017/03/02 Python
Python打印“菱形”星号代码方法
2018/02/05 Python
python之django母板页面的使用
2018/07/03 Python
简单谈谈python基本数据类型
2018/09/26 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
ipad上运行python的方法步骤
2019/10/12 Python
django 外键创建注意事项说明
2020/05/20 Python
Python脚本破解压缩文件口令实例教程(zipfile)
2020/06/14 Python
澳大利亚正品化妆品之家:Cosmetic Capital
2017/07/03 全球购物
梅西酒窖:Macy’s Wine Cellar
2018/01/07 全球购物
考试作弊检讨书大全
2014/02/18 职场文书
作风建设年度心得体会
2014/10/29 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书
MySql学习笔记之事务隔离级别详解
2021/05/12 MySQL
Python基础 括号()[]{}的详解
2021/11/07 Python