`
Liner
  • 浏览: 141570 次
  • 性别: Icon_minigender_1
  • 来自: 西南边陲
社区版块
存档分类
最新评论

几个文字加密的 JS 简洁算法(续2)--进制乱序法

阅读更多
续前一篇博文《几个文字加密的简洁算法和一些个人的想法》——字符平移法
以及上一篇博文《几个文字加密的简洁算法(续)》——字符错位法
这里提供第三种加密方法——对字符 Unicode 值 的 “进制转换” 法


先说点废话……

0x7a 是英文小写字母‘z’的编码值,这是编码规范规定的,机器知道,程序员也知道。
0x7a 是十进制 122——这,为什么呢? ……因为

十六进制是由 0123456789abcdef 十六个字符来表达的,并且,a 代表 10、b 代表 11,以此类推。122 用十六进制转换下来就是 7a。so…… 单纯的进制转换其实是不能实现加密的

但是,如果 a 不代表 10,b 不代表 11,9 代表的是 0 或其它呢——也就是说,进制表中各字符所代表的值是 随机 的,不符合常规约定,那…… 7a 代表什么呢?  你无法知道,机器也不可能明白!

所以,如果指定一个字符 随机排列 的进制表,依此转换字符编码值,那除非你有那个原始的进制表,否则你是无法知道 7a 是哪个字符的值(即:0x7a != 122)。

“进制乱序法”——这里,随机排布的进制表就是密钥

根据 Unicode-16 的编码规范,CJK 字符集中 20902 个汉字的编码值在 65535 以内(即 2 的 16 次方),如果用十六进制表示,每个字需要4个进制字符表达,1 变 4! 密文增加得太多了,不划算! 折中,取 3 个进制字符表达,需要 41 进制 才能涵盖 65535 的码值(41*41*41 = 68921 > 65535)。

原则上,进制表字符可以采用任意 8 bit 字符,但考虑通用性,以及字符在各种网络上的正常传输,这里仅采用英文字符 a-z,和 A-Z,区分大小写共 52 个字符 作为进制表字符候选。

注意:算法中对转换后的字符串(进制表字符)增加了“平移加密”(见 算法1 ) 操作,使得加密强度更高了。


算法3:进制乱序法

(function() {
    //
    // 进制转换-加密:
    // 采用 [a-zA-Z] 52 个字符随机排列成进制表,对字符的值进行转换。
    // 固定 3 位字符,41 进制,字符值最大可为 68920(> 65535)。
    // 特点:
    // 1. 密文为纯大小写英文字母,及原有的 [\s\n\r];
    // 2. 增加了平移操作,双重加密;
    // 3. key[0-40] 为进制表,逆向 16-25 位作为平移密钥;
    // 4. 进制表段字符不可重复。
    // 5. 空白、换行和回车 [\s\n\r] 不加密。
    // 缺点:
    // 密文会比原文长,单字节字符会增长得较多。
    // 推荐:
    // 适用于任意类型的文本加密,网络环境可采用压缩传输;
    // 注意:
    // key 字符串不能含非 [a-zA-Z] 字符(关联数组)。
    //
    // @param string key  - 进制表串(length >= 41)
    // @return string  - 转换后的字符串
    //
    String.prototype._41hex = (function()
    {
        var _k, _k2, _sz;

        return  function( key ) {
            if (key.length < 41)  return null;

            if (_k != key) {
                _sz = key.charCodeAt(40) % 10 + 16,
                _k2 = key.slice(-_sz).split('');
                for (var _i=0; _i<_sz; ++_i) {
                    _k2[_i] = _k2[_i].charCodeAt(0);
                }
                _k = key;
            }
            var _cnt = 0;
            return  this.replace(/[^\s\n\r]/g, function(s) {
                var _n = s.charCodeAt(0);
                return  key.charAt(parseInt(_n/1681)) + key.charAt(parseInt(_n%1681/41)) + key.charAt(_n%41);

            }).replace(/[a-zA-Z]/g, function(s) {
                var _n = s.charCodeAt(0),
                    _beg = (_n < 0x61) ? 0x41 : 0x61,
                    _c = _n - _beg;
                return  String.fromCharCode((_c+_k2[_cnt++%_sz])%26 + _beg);
            });
        };
    })();

    //
    // 进制转换-解密
    // @return string  - 恢复后的字符串
    //
    String.prototype._un41hex = (function()
    {
        var _k, _k2 = [], _sz, _tbl = {};

        return  function( key ) {
            if (key.length < 41)  return null;

            if (_k != key) {
                // 逆向,防止属性值覆盖
                for (var _i=key.length-1; _i>=0; --_i) {
                    _tbl[key.charAt(_i)] = _i;
                    _k2[_i] = key.charCodeAt(_i);
                }
                _sz = _k2[40] % 10 + 16;
                _k2 = _k2.slice(-_sz);
                _k  = key;
            }
            var _cnt = 0;
            return  this.replace(/[a-zA-Z]/g, function(s) {
                var _n = s.charCodeAt(0),
                    _beg = (_n < 0x61) ? 0x41 : 0x61,
                    _c = _n - _beg;
                return  String.fromCharCode((_c-_k2[_cnt++%_sz]%26+26)%26 + _beg);

            }).replace(/[a-zA-Z]{3}/g, function(s) {
                var _n = _tbl[s.charAt(0)]*1681 + _tbl[s.charAt(1)]*41 + _tbl[s.charAt(2)];
                return  String.fromCharCode(_n);
            });
        };
    })();

})();


优化单字节字符串加密

——采用 2 个进制表字符,用 16 进制表达,降低密文的增长长度,仅适用于码值在 0xff 以内的字符(码值超出的字符——如中文会 原样保留)。

(function() {
    //
    // 进制转换:单字节字符版本-加密。
    // 采用 16 进制,固定 2 个字符。
    // 特点:
    // 值大于 0xff 的字符会原样保留,即不加密非拉丁字符。
    //
    // @param string key  - 进制表串(length >= 16)
    // @return string  - 转换后的字符串
    //
    String.prototype._16hex = (function()
    {
        var _k, _k2, _sz;

        return  function( key ) {
            if (key.length < 16)  return null;

            if (_k != key) {
                // 加强平移密钥
                _sz = key.charCodeAt(15) % (key.length-6) + 6,
                _k2 = key.slice(-_sz).split('');
                for (var _i=0; _i<_sz; ++_i) {
                    _k2[_i] = _k2[_i].charCodeAt(0);
                }
                _k = key;
            }
            var _cnt = 0;
            return  this.replace(/[\x21-\xff]/g, function(s) {
                var _n = s.charCodeAt(0);
                return  key.charAt(parseInt(_n/16)) + key.charAt(_n%16);

            }).replace(/[a-zA-Z]/g, function(s) {
                var _n = s.charCodeAt(0),
                    _beg = (_n < 0x61) ? 0x41 : 0x61,
                    _c = _n - _beg;
                return  String.fromCharCode((_c+_k2[_cnt++%_sz])%26 + _beg);
            });
        };
    })();

    //
    // 进制转换:单字节字符版本-解密
    // @return string  - 恢复后的字符串
    //
    String.prototype._un16hex = (function()
    {
        var _k, _k2 = [], _sz, _tbl = {};

        return  function( key ) {
            if (key.length < 16)  return null;

            if (_k != key) {
                // 逆向,防止属性值覆盖
                for (var _i=key.length-1; _i>=0; --_i) {
                    _tbl[key.charAt(_i)] = _i;
                    _k2[_i] = key.charCodeAt(_i);
                }
                _sz = _k2[15] % (key.length-6) + 6;
                _k2 = _k2.slice(-_sz);
                _k  = key;
            }
            var _cnt = 0;
            return  this.replace(/[a-zA-Z]/g, function(s) {
                var _n = s.charCodeAt(0),
                    _beg = (_n < 0x61) ? 0x41 : 0x61,
                    _c = _n - _beg;
                return  String.fromCharCode((_c-_k2[_cnt++%_sz]%26+26)%26 + _beg);

            }).replace(/[a-zA-Z]{2}/g, function(s) {
                var _n = _tbl[s.charAt(0)]*16 + _tbl[s.charAt(1)];
                return  String.fromCharCode(_n);
            });
        };
    })();

})();


用法:
<script language="JavaScript">
    var _str = "中文字符串和 English char string 的 JS 加密 Test. 包含一些标点符号,*@%! 等。";
    // [a-zA-Z] 的随机排列
    var _t = 'DsCqrtEcbFLOuijMklNmUVnwGvHopIJKxyzABaSTWPQRXdeYfhZg';
    var _enc3 = _str._41hex(_t);
    alert(_enc3);
    alert(_enc3._un41hex(_t));
</script>


特点:
1.  密文会增长,是原始字符串长度的 3 倍(或 2 倍),但适用于各种字符集;
2.  密文是英文大小写字母,便于各类环境下的数据传输,保留空格和换行不做转换,节约编码长度;
3.  因对密文进行了平移操作,所以即便只是统计 41 进制表中包含了哪些字符也不可能(破解需要知道进制表中有哪些字符和如何排列)。


扯了好多哦…………快过节了,没事多唠唠哈哈,俺的时间不值钱……呵呵

分享到:
评论
2 楼 Liner 2011-02-10  
zyengogo 写道
这个加密没大看明白呢?

试试怎么把十进制转换成十六进制——用简单的进位法

return  key.charAt(parseInt(_n/16)) + key.charAt(_n%16); 

就这一行,可以假设 _n 不会超过 255
1 楼 zyengogo 2011-02-10  
这个加密没大看明白呢?

相关推荐

    des加密算法-显示16进制

    在本实验中,我们关注的是如何使用DES算法进行加密,并将结果以16进制的形式展示出来。以下是关于DES加密算法及其在16进制显示中的相关知识。 首先,DES算法基于Feistel网络结构,它将原始明文分为左半部分(L0)和...

    VB--十进制,八进制,十六进制,二进制相互转换大全

    以上四个函数覆盖了常见的进制转换需求,在多种编程任务中都有广泛的应用,例如数据压缩、加密算法、网络协议解析等。理解并掌握这些转换逻辑,对于深入学习计算机科学基础和提高编程能力都大有裨益。

    16进制转换器( ASCII->16进制数)

    每个ASCII字符都对应一个唯一的7位二进制数字,这个数字可以转换为16进制来提供更简洁的表示方式。 16进制是一种逢16进一的计数方式,它使用0到9的阿拉伯数字和A到F的字母(代表10到15)来表示数字。16进制转换通常...

    易语言2-62进制转换器

    这种进制系统的优点在于它可以表示更大的数值,并且在某些算法或数据表示中可能更简洁。 4. **源码分析**:易语言2-62进制转换器的源码中,我们可以学习如何实现这个功能。主要包括以下几个步骤: - **读取输入**...

    base64--二进制流的还原

    2. **解码**:当你接收到一个Base64字符串并需要还原为原始二进制数据时,可以使用`Data`类的初始化方法`init(base64Encoded:)`来完成。这个方法会尝试将Base64字符串转换回原始的二进制数据流。 3. **错误处理**:...

    JavaScript的加密算法类库:crypto-js

    JavaScript的加密算法类库Crypto-js是前端开发中用于安全数据处理的重要工具,它提供了一系列的加密和解密功能,使得开发者无需后端支持就能在浏览器环境中实现数据的安全传输和存储。这个库支持多种常见的加密算法...

    大整数任意进制转换(2-62进制)

    大整数任意进制转换是一个核心概念,尤其是在处理大量数据、加密算法以及高级编程语言中。本文将深入探讨这个主题,结合"大整数任意进制转换(2-62进制)"的软件特点,解析其中涉及的关键知识点。 首先,我们来理解...

    Java中3DES加密解密示例(封装byte数组16进制互转)

    Java 中的 3DES 加密解密示例(封装 byte 数组和 16 进制字符串互转) 在 Java 中,3DES 加密是一种常用的加密算法,它可以将明文数据转换为密文数据,以保护数据的安全性。在本示例中,我们将展示如何使用 3DES ...

    ASCLL-十六进制-十进制对照表

    由于每个ASCII码都对应一个十进制数和一个十六进制数,因此就有了ASCII-十六进制-十进制对照表。 在计算机中,数据的存储和处理都是以二进制形式进行的。为了方便人类理解和操作数据,需要将二进制数据转化为人们...

    Python3.7.2中文文档-标准库-Python二进制数据服务

    2. **binascii模块**: 这个模块提供了许多二进制与ASCII之间的转换函数,例如将十六进制字符串转换为字节,或将字节转换为Base64编码。这对于在不同的数据格式之间进行转换非常有用。 3. **struct模块**: 结构化...

    2-62进制转换器 编程 计算 算法

    2-62进制转换器是一种工具,它能够帮助用户将数字从二进制(base-2)形式转换为其他进制,甚至包括非标准的62进制(base-62)。这种转换在计算机科学、网络编码、加密算法和数据表示等多个领域都有应用。 二进制是...

    论文研究-一种基于IDEA的十进制短分组加密算法.pdf

    IDEA是一个著名的加密算法,被广泛应用于各种领域,最著名的有PGP。基于IDEA算法,提出了一种新颖的十进制短分组加密技术。针对十进制数运算的特点,在加密算法中定义了三种新的运算,并从理论上证明新的运算能保证...

    Javascript实现的SHA-256加密算法完整实例

    JavaScript实现SHA-256加密算法的实例主要涉及以下几个关键部分: 1. **位运算基础**:JavaScript提供了位运算符,包括按位与(&)、按位或(|)、异或(^)、非(~)、左移()和右移(&gt;&gt;)。位运算是SHA-256算法的基石,因为...

    易语言2-62进制转换器源码

    进制转换的核心算法主要包括以下几个步骤: 1. 分数表示:将任意进制的数转换为二进制表示,这通常通过除以目标进制并取余的方式来完成。 2. 进制转换:将二进制数转换为其他进制,例如十进制或62进制,这可以通过...

    安全相关-加密工具-兜帽代码乱序工具 v1.2.zip

    网络-计算机-安全相关

    C# 对称法加密、解密dataset,算法使用了二进制流得方式进行加密、解密,提高效率

    2. **创建加密和解密流**:C#提供了CryptoStream类,它可以与任何其他流(如FileStream)一起使用,以进行加密和解密操作。我们需要将密钥和IV设置到加密器(Encryptor)和解密器(Decryptor)中。 3. **二进制流的...

    Python-基于二进制代码生成YARA规则

    实际应用中,你可能需要更复杂的规则,比如查找特定的API调用序列、特定的加密算法痕迹或特定的内存偏移。这可能涉及到解析PE文件结构、反汇编代码或分析内存映像。Python中的库,如`pefile`用于PE文件分析,`...

    10-16进制互转软件

    在实际工作中,当涉及到对内存地址的解析、数据压缩、加密算法的实现等场景时,熟悉进制转换能够帮助技术人员更加高效和精确地处理信息。 在计算机科学的实践中,进制转换不仅是将一种数制转化为另一种数制那么简单...

    前端纯js加密、以及后端java解密代码 js 实现国密sm2、sm3、sm4 加密解密demo

    前端纯js加密、以及后端java解密代码。国密即国家密码局认定的国产密码算法。常用的主要有SM2,SM3,SM4。 SM2:椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,为非对称加密,基于ECC。该算法已公开。由于该...

    vb加密算法(6层加密)

    一共6层加密 1。字符----》ASCII ...由于本人是菜鸟,所以这个加密算法可能很烂,请见谅! 有一部分文字和字符转化后可能无法复原,如果能解决请联系我,谢谢! 邮箱:834449164@qq.com QQ:834449164

Global site tag (gtag.js) - Google Analytics