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 getComputedStyle获取和设置style的原理
Oct 10 Javascript
jquery 缓存问题的几个解决方法
Nov 11 Javascript
div浮层,滚动条移动,位置保持不变的4种方法汇总
Dec 11 Javascript
利用Keydown事件阻止用户输入实现代码
Mar 11 Javascript
纯JS实现根据CSS的class选择DOM
Mar 22 Javascript
JavaScript实现DIV层拖动及动态增加新层的方法
May 12 Javascript
Bootstrap3制作自己的导航栏
May 12 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
Dec 28 Javascript
js 性能优化之算法和流程控制
Feb 15 Javascript
jQuery实现拖动效果的实例代码
Jun 25 jQuery
微信小程序实现日历签到
Sep 21 Javascript
JS实现手风琴特效
Nov 08 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
如何跨站抓取别的站点的页面的补充
2006/10/09 PHP
免费的ip数据库淘宝IP地址库简介和PHP调用实例
2014/04/08 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
PHP字符串word末字符实现大小写互换的方法
2014/11/10 PHP
PHP使用递归生成文章树
2015/04/21 PHP
显示、隐藏密码
2006/07/01 Javascript
jquery ready()的几种实现方法小结
2010/06/18 Javascript
jQuery 源码分析笔记(4) Ready函数
2011/06/02 Javascript
js实现点小图看大图效果的思路及示例代码
2013/10/28 Javascript
原始XMLHttpRequest方法详情回顾
2013/11/28 Javascript
Javascript实现返回上一页面并刷新的小例子
2013/12/11 Javascript
nodejs URL模块操作URL相关方法介绍
2015/03/03 NodeJs
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
深入解析nodejs HTTP服务
2017/07/25 NodeJs
Vue导出页面为PDF格式的实现思路
2018/07/31 Javascript
NodeJS 实现多语言的示例代码
2018/09/11 NodeJs
Vue实现星级评价效果实例详解
2019/12/30 Javascript
[02:22:36]《加油!DOTA》总决赛
2014/09/19 DOTA
[01:04:09]DOTA2-DPC中国联赛 正赛 iG vs VG BO3 第二场 2月2日
2021/03/11 DOTA
Python操作SQLite数据库的方法详解
2017/06/16 Python
python实现两个文件合并功能
2018/04/01 Python
matplotlib给子图添加图例的方法
2018/08/03 Python
彻底搞懂 python 中文乱码问题(深入分析)
2020/02/28 Python
python Timer 类使用介绍
2020/12/28 Python
英国Zoro工具:手动工具,电动工具和个人防护用品
2016/11/02 全球购物
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
班级入场式解说词
2014/02/01 职场文书
环境工程专业自荐信
2014/03/03 职场文书
2014离婚协议书范文
2014/09/10 职场文书
销售辞职信范文
2015/03/02 职场文书
现实表现证明材料
2015/06/19 职场文书
青少年法制教育心得体会
2016/01/14 职场文书
2016廉洁从政心得体会
2016/01/19 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
python爬取豆瓣电影TOP250数据
2021/05/23 Python