Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 1104|回复: 0

针对文字加密的简单 JS 加密算法 --进制乱序法改良版

  [复制链接]

该用户从未签到

发表于 2011-10-29 08:22:54 | 显示全部楼层 |阅读模式
在上一篇文章《普通 http 网络下数据的安全传输(设计原理)》中,我曾经推荐浏览器和服务器之间的加密通讯宜采用《几个文字加密的 JS 简洁算法(续2)--进制乱序法》中提及的算法,但那个算法有密文增长较多的缺点。考虑实用性,这里作了完全重新的设计,可以自动识别单双字节字符,单字节字符用 2 位 16 进制表示,双字节字符用 3 位 41 进制表示,从而降低了密文的增长幅度。


如认为汉字占用 2 个字节,则中文文本加密后的密文增长幅度为 1.5 倍——与 UTF-8 存储汉字占用字节相同;
英文文本加密后密文的增长原理上是 2 倍,但由于空格是英文中的词汇分界符,在英文文本中大量存在,而空格是不加密的(只占 1 字节),故实际的密文增长并没那么多。
综合评估,在中英文混合的文章中,密文的增长大概在 1.6 ~ 1.8 之间,这并不算严重(如果对密文的增长很敏感,可以用另外两个不增长密文的算法)。
这里把改良的版本贴出来,希望能对需要的人有所帮助。

算法 3: 进制乱序法 -- 改良版

javascript代码
(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, &#39':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;   
    };   
  
})();  

(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;
    };

})();

用法:
Javascript代码
<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));  

<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 命令行执行如下代码得到。

Php代码
$a=range(0,61); shuffle($a); echo join(',', $a);  // _k3 只需前 57 项元素。  

    $a=range(0,61); shuffle($a); echo join(',', $a);  // _k3 只需前 57 项元素。


说明:本人原创,代码可以自由使用!
回复

使用道具 举报

该用户从未签到

发表于 2012-5-10 22:28:53 | 显示全部楼层
这个还不错,好帖子,大家谈谈
悠哉网www.sadnook.com
中国讲座在线www.douya5.cn
尚生活www.027up.com
悠哉教育www.yoozai.com
武汉数据www.whdata.net
要爱你www.1l0.cn








悠哉网www.sadnook.com
中国讲座在线www.douya5.cn
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-11-21 23:43:35 | 显示全部楼层
非常感谢啊!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-5-18 17:28 , Processed in 0.495509 second(s), 34 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表