浏览 2351 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-02-12
最后修改:2011-02-12
在上一篇文章《普通 http 网络下数据的安全传输(设计原理)》中,我曾经推荐浏览器和服务器之间的加密通讯宜采用《几个文字加密的 JS 简洁算法(续2)--进制乱序法》中提及的算法,但那个算法有密文增长较多的缺点。考虑实用性,这里作了完全重新的设计,可以自动识别单双字节字符,单字节字符用 2 位 16 进制表示,双字节字符用 3 位 41 进制表示,从而降低了密文的增长幅度。
算法 3: 进制乱序法 -- 改良版 (function() { // // 密文字符集(size:62)。 // [0-9A-Za-z] // var _hexCHS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; // // 密文字符顺序映射。 // 顺序与 _hexCHS 同,从 0 开始。 // var _hexTBL = { '0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'A':10, 'B':11, 'C':12, 'D':13, 'E':14, 'F':15, 'G':16, 'H':17, 'I':18, 'J':19, 'K':20, 'L':21, 'M':22, 'N':23, 'O':24, 'P':25, 'Q':26, 'R':27, 'S':28, 'T':29, 'U':30, 'V':31, 'W':32, 'X':33, 'Y':34, 'Z':35, 'a':36, 'b':37, 'c':38, 'd':39, 'e':40, 'f':41, 'g':42, 'h':43, 'i':44, 'j':45, 'k':46, 'l':47, 'm':48, 'n':49, 'o':50, 'p':51, 'q':52, 'r':53, 's':54, 't':55, 'u':56, 'v':57, 'w':58, 'x':59, 'y':60, 'z':61 }; // // 进制转换加密法 // 原理: // 用 [0-9A-Za-z] 62 个字符的随机排列作为进制表对字符的值进行转换。 // 特点: // 1. 密文为数字和大小写英文字母,及原有的 [\s\n\r]; // 2. 增加了密文字符的平移操作,提高加密强度; // 3. 可自动识别单双字节字符并进行相应编码; // 4. 双字节字符用 3 位 41 进制表示,最大可表示 68920 的字值; // 5. 单字节字符用 2 位 16 进制表示,最大可表示 255 的字值; // 6. 空白、换行和回车 [\s\n\r] 保持原样。 // 缺点: // 密文会比原文长,中文视宽增长 1.5 倍(一个汉字算 2 字节宽); // 考虑空白和换行/回车不处理,英文增长 < 2 倍。 // 推荐: // 可用于任意类型的文本加密,由于密文为规范的 [\w],适于各类环境。 // // 参数: // key[0-57) 间的值小于 62 且唯一,其后的值可任意和重复; // key[0-16) 为 16 进制字符表,key[16-57) 为 41 进制字符表。 // // @param array key - [0-61] 互斥值数组,length >= 57 // Hexch = function( key ) { if (key.length < 57) { throw new Error('the key is too short.'); } // 平移密钥 this._sz = _hexCHS.charCodeAt(key[15]) % (key.length-20) + 10, this._ks = key.slice(-this._sz); for (var _i=0; _i<this._sz; ++_i) { this._ks[_i] = _hexCHS.charCodeAt(this._ks[_i]%62); } this._k16 = [], this._k41 = []; this._t16 = {}, this._t41 = {}; for (var _i=0; _i<16; ++_i) { this._k16[_i] = _hexCHS.charAt(key[_i]); this._t16[this._k16[_i]] = _i; } for (var _i=0; _i<41; ++_i) { this._k41[_i] = _hexCHS.charAt(key[_i+16]); this._t41[this._k41[_i]] = _i; } }; // 加密 Hexch.prototype.enc = function( s ) { var _k16 = this._k16, _k41 = this._k41, _ks = this._ks, _sz = this._sz, _cnt = 0; return s.replace(/[^\s\n\r]/g, function( ch ) { var _n = ch.charCodeAt(0); return (_n <= 0xff) ? _k16[parseInt(_n/16)] + _k16[_n%16] : _k41[parseInt(_n/1681)] + _k41[parseInt(_n%1681/41)] + _k41[_n%41] // 平移 }).replace(/[0-9A-Za-z]/g, function( ch ) { return _hexCHS.charAt((_hexTBL[ch] + _ks[_cnt++%_sz]) % 62); }); }; // 解密 Hexch.prototype.dec = function( s ) { var _t16 = this._t16, _t41 = this._t41, _ks = this._ks, _sz = this._sz, _cnt = 0; var _s = s.replace(/[0-9A-Za-z]/g, function( ch ) { return _hexCHS.charAt((_hexTBL[ch] - _ks[_cnt++%_sz]%62 + 62) % 62); }); var _rs = ''; for (var _i=0; _i<_s.length;) { var _ch = _s.charAt(_i); if (/[\s\n\r]/.test(_ch)) { _rs += _ch; ++_i; } else if (_t16[_ch] !== undefined) { _rs += String.fromCharCode(_t16[_s.charAt(_i)]*16 + _t16[_s.charAt(_i+1)]); _i += 2; } else { _rs += String.fromCharCode(_t41[_s.charAt(_i)]*1681 + _t41[_s.charAt(_i+1)]*41 + _t41[_s.charAt(_i+2)]); _i += 3; } } return _rs; }; })(); 用法: <script language="JavaScript"> var _str = "中文字符串和 English char string 的 JS 加密 1234. 包含一些标点符号,*@%! 等。"; var _k3 = [61,37,44,31,34,7,24,6,43,12,27,3,25,29,60,33,35,41,58,2,51,49,9,5,59,11,42,32,22,40,4,57,50,38,8,56,21,19,52,53,16,28,1,26,47,17,54,46,10,23,55,13,14,20,15,36,18]; var _o = new Hexch(_k3); var _enc3 = _o.enc(_str); alert(_enc3) //7Eg9K4UTzvBzgBPPTC eEb6xHzJHQIKEq jIhRYSpl MNCfJqxNzsHK KlP hmuo 61BNLv Nhcvd4g9cr aDkCWBJXPgR6y9iiG6GRQx4PT5AYatm1rsS rnQxSr alert(_o.dec(_enc3)); 注: _k3 是一个 [0-61] 的互斥值随机排列数组,可用 PHP 命令行执行如下代码得到。 $a=range(0,61); shuffle($a); echo join(',', $a); // _k3 只需前 57 项元素。 说明:本人原创,代码可以自由使用! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |