XXTEA算法的结构非常简单,只需要执行加法、异或和寄存的硬件即可,且软件实现的代码非常短小,具有可移植性。

维基百科地址:http://en.wikipedia.org/wiki/XXTEA

之前分析QQ, 微信协议的时候, 发现有些场合用的也是XXTEA算法;

为了能在白鹭项目里面使用, 封装了个TS版本;

感谢xxtea-nodejs的作者~

https://github.com/xxtea/xxtea-nodejs

使用例子:

let _xxtea = xxtea.getInstance();    //获取实例

let raw_data = 'hello, xxtea'
let encrypt_data = _xxtea.encrypt(raw_data,  "passwd"); //加密
let decrypt_data = _xxtea.decrypt(encrypt_data ,  "passwd"); //解密

代码:

//

//xxtea.ts

class xxtea
{
    private constructor(){}
    private static instance: xxtea;
    private _protoBufRoot;
    static getInstance(): xxtea{
        if(!xxtea.instance){
            xxtea.instance = new xxtea();
            xxtea.instance.initInstance();
        }
        return this.instance;
    }
    //init function
    private initInstance(){
    }
    ///
    private delta:number = 0x9E3779B9;
    public toUint8Array(v, includeLength) {
        var length = v.length;
        var n = length << 2;
        if (includeLength) {
            var m = v[length - 1];
            n -= 4;
            if ((m < n - 3) || (m > n)) {
                return null;
            }
            n = m;
        }
        var bytes = new Uint8Array(n);
        for (var i = 0; i < n; ++i) {
            bytes[i] = v[i >> 2] >> ((i & 3) << 3);
        }
        return bytes;
    }

public toUint32Array(bytes, includeLength) {
        var length = bytes.length;
        var n = length >> 2;
        if ((length & 3) !== 0) {
            ++n;
        }
        var v;
        if (includeLength) {
            v = new Uint32Array(n + 1);
            v[n] = length;
        }
        else {
            v = new Uint32Array(n);
        }
        for (var i = 0; i < length; ++i) {
            v[i >> 2] |= bytes[i] << ((i & 3) << 3);
        }
        return v;
    }

public mx(sum, y, z, p, e, k) {
        return ((z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4)) ^ ((sum ^ y) + (k[p & 3 ^ e] ^ z));
    }

public fixk(k) {
        if (k.length < 16) {
            var key = new Uint8Array(16);
            key.set(k);
            k = key;
        }
        return k;
    }

public encryptUint32Array(v, k) {
        var length = v.length;
        var n = length - 1;
        var y, z, sum, e, p, q;
        z = v[n];
        sum = 0;
        for (q = Math.floor(6 + 52/length) | 0; q > 0; --q) {
            sum += this.delta;
            e = sum >>> 2 & 3;
            for (p = 0; p < n; ++p) {
                y = v[p + 1];
                z = v[p] += this.mx(sum, y, z, p, e, k);
            }
            y = v[0];
            z = v[n] += this.mx(sum, y, z, p, e, k);
        }
        return v;
    }

public decryptUint32Array(v, k) {
        var length = v.length;
        var n = length - 1;
        var y, z, sum, e, p, q;
        y = v[0];
        q = Math.floor(6 + 52/length);
        for (sum = q * this.delta; sum !== 0; sum -= this.delta) {
            e = sum >>> 2 & 3;
            for (p = n; p > 0; --p) {
                z = v[p - 1];
                y = v[p] -= this.mx(sum, y, z, p, e, k);
            }
            z = v[n];
            y = v[0] -= this.mx(sum, y, z, p, e, k);
        }
        return v;
    }

public toBytes(str) {
        var n = str.length;
        // A single code unit uses at most 3 bytes.
        // Two code units at most 4.
        var bytes = new Uint8Array(n * 3);
        var length = 0;
        for (var i = 0; i < n; i++) {
            var codeUnit = str.charCodeAt(i);
            if (codeUnit < 0x80) {
                bytes[length++] = codeUnit;
            }
            else if (codeUnit < 0x800) {
                bytes[length++] = 0xC0 | (codeUnit >> 6);
                bytes[length++] = 0x80 | (codeUnit & 0x3F);
            }
            else if (codeUnit < 0xD800 || codeUnit > 0xDFFF) {
                bytes[length++] = 0xE0 | (codeUnit >> 12);
                bytes[length++] = 0x80 | ((codeUnit >> 6) & 0x3F);
                bytes[length++] = 0x80 | (codeUnit & 0x3F);
            }
            else {
                if (i + 1 < n) {
                    var nextCodeUnit = str.charCodeAt(i + 1);
                    if (codeUnit < 0xDC00 && 0xDC00 <= nextCodeUnit && nextCodeUnit <= 0xDFFF) {
                        var rune = (((codeUnit & 0x03FF) << 10) | (nextCodeUnit & 0x03FF)) + 0x010000;
                        bytes[length++] = 0xF0 | (rune >> 18);
                        bytes[length++] = 0x80 | ((rune >> 12) & 0x3F);
                        bytes[length++] = 0x80 | ((rune >> 6) & 0x3F);
                        bytes[length++] = 0x80 | (rune & 0x3F);
                        i++;
                        continue;
                    }
                }
                throw new Error('Malformed string');
            }
        }
        return bytes.subarray(0, length);
    }

public toShortString(bytes, n) {
        var charCodes = new Uint16Array(n);
        var i = 0, off = 0;
        for (var len = bytes.length; i < n && off < len; i++) {
            var unit = bytes[off++];
            switch (unit >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                charCodes[i] = unit;
                break;
            case 12:
            case 13:
                if (off < len) {
                    charCodes[i] = ((unit & 0x1F) << 6) |
                                    (bytes[off++] & 0x3F);
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            case 14:
                if (off + 1 < len) {
                    charCodes[i] = ((unit & 0x0F) << 12) |
                                   ((bytes[off++] & 0x3F) << 6) |
                                   (bytes[off++] & 0x3F);
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            case 15:
                if (off + 2 < len) {
                    var rune = (((unit & 0x07) << 18) |
                                ((bytes[off++] & 0x3F) << 12) |
                                ((bytes[off++] & 0x3F) << 6) |
                                (bytes[off++] & 0x3F)) - 0x10000;
                    if (0 <= rune && rune <= 0xFFFFF) {
                        charCodes[i++] = (((rune >> 10) & 0x03FF) | 0xD800);
                        charCodes[i] = ((rune & 0x03FF) | 0xDC00);
                    }
                    else {
                        throw new Error('Character outside valid Unicode range: 0x' + rune.toString(16));
                    }
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            default:
                throw new Error('Bad UTF-8 encoding 0x' + unit.toString(16));
            }
        }
        if (i < n) {
            charCodes = charCodes.subarray(0, i);
        }
        return String.fromCharCode.apply(String, charCodes);
    }

public toLongString(bytes, n) {
        var buf = [];
        var charCodes = new Uint16Array(0xFFFF);
        var i = 0, off = 0;
        for (var len = bytes.length; i < n && off < len; i++) {
            var unit = bytes[off++];
            switch (unit >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                charCodes[i] = unit;
                break;
            case 12:
            case 13:
                if (off < len) {
                    charCodes[i] = ((unit & 0x1F) << 6) |
                                    (bytes[off++] & 0x3F);
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            case 14:
                if (off + 1 < len) {
                    charCodes[i] = ((unit & 0x0F) << 12) |
                                   ((bytes[off++] & 0x3F) << 6) |
                                   (bytes[off++] & 0x3F);
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            case 15:
                if (off + 2 < len) {
                    var rune = (((unit & 0x07) << 18) |
                                ((bytes[off++] & 0x3F) << 12) |
                                ((bytes[off++] & 0x3F) << 6) |
                                (bytes[off++] & 0x3F)) - 0x10000;
                    if (0 <= rune && rune <= 0xFFFFF) {
                        charCodes[i++] = (((rune >> 10) & 0x03FF) | 0xD800);
                        charCodes[i] = ((rune & 0x03FF) | 0xDC00);
                    }
                    else {
                        throw new Error('Character outside valid Unicode range: 0x' + rune.toString(16));
                    }
                }
                else {
                    throw new Error('Unfinished UTF-8 octet sequence');
                }
                break;
            default:
                throw new Error('Bad UTF-8 encoding 0x' + unit.toString(16));
            }
            if (i >= 65534) {
                var size = i + 1;
                buf.push(String.fromCharCode.apply(String, charCodes.subarray(0, size)));
                n -= size;
                i = -1;
            }
        }
        if (i > 0) {
            buf.push(String.fromCharCode.apply(String, charCodes.subarray(0, i)));
        }
        return buf.join('');
    }

public toString(bytes) {
        var n = bytes.length;
        if (n === 0) return '';
        return ((n < 100000) ?
                this.toShortString(bytes, n) :
                this.toLongString(bytes, n));
    }

public encrypt(data, key) {
        if (typeof data === 'string') data = this.toBytes(data);
        if (typeof key === 'string') key = this.toBytes(key);
        if (data === undefined || data === null || data.length === 0) {
            return data;
        }
        return this.toUint8Array(this.encryptUint32Array(this.toUint32Array(data, true), this.toUint32Array(this.fixk(key), false)), false);
    }

public encryptToString(data, key) {
        return this.encrypt(data, key).toString('base64');
    }

public decrypt(data, key) {
        if (typeof data === 'string') data = data.toString();
        if (typeof key === 'string') key = this.toBytes(key);
        if (data === undefined || data === null || data.length === 0) {
            return data;
        }
        return this.toUint8Array(this.decryptUint32Array(this.toUint32Array(data, false), this.toUint32Array(this.fixk(key), false)), true);
    }

public decryptToString(data, key) {
        return this.toString(this.decrypt(data, key));
    }
}

白鹭引擎加密算法 - XXTEA -typescript相关推荐

  1. 手把手教你架构3d游戏引擎pdf_白鹭引擎团队即将发布 Egret Pro,并公布后续路线图...

    各位开发者好. 春节前,白鹭引擎团队发布了 Egret3D 1.4,引入了大量新特性.上周,白鹭引擎团队发布了 5.2.14 版本,修复了多个白鹭引擎2D渲染器相关的 BUG,接下来我们会在下周继续发 ...

  2. 开源,免费,跨平台——白鹭引擎(Egret Engine)

    http://blog.zinewow.com/post/376.html Egret Engine(白鹭引擎)是一款使用 TypeScript 语言构建的开源免费的移动游戏引擎.白鹭引擎的核心定位是 ...

  3. 白鹭引擎 4.0 发布 让重度H5游戏研发更简单

    今天,白鹭引擎 4.0正式发布,此次版本包含众多新特性,主要提升了目前市场上重度HTML5游戏性能,内存以及开发效率等,为开发者提供强有力的技术支撑,保证用户在开发重度游戏时可以随心所欲的实现游戏功能 ...

  4. 白鹭引擎(Egret Engine )

    什么是白鹭引擎 Egret引擎是一个开源免费的游戏框架,用于构建二维游戏.演示程序和其他图形界面交互应用等.Egret使用TypeScript脚本语言开发.当游戏完成最终的打包后,可以将程序转换为HT ...

  5. WebAssembly在白鹭引擎5.0中的实践

    作者:王泽,北京白鹭时代信息技术有限公司白鹭引擎首席架构师.目前主要聚焦于HTML5游戏引擎开发.TypeScript以及WebAssembly技术相关的研究与实践工作. 责编:陈秋歌,关注前端开发领 ...

  6. 白鹭安装node_Egret Engine(白鹭引擎)介绍及windows下安装

    Egret Engine简要介绍----- Egret Engine(白鹭引擎)[Egret Engine官网:http://www.egret-labs.org/]是一款使用TypeScript语言 ...

  7. 坚守初心,白鹭引擎七年之痒

    各位开发者好,我是白鹭引擎团队的王泽. 七年前的今天,我敲下了白鹭引擎的第一行代码,此时此刻我的孩子也终于要呱呱落地,即将成为一个父亲,我也有很多感慨. 这两年经常有一些朋友来找我关心白鹭的动向,因为 ...

  8. 白鹭游戏引擎html5,Egret Engine(白鹭引擎)V2.5.6 官方版

    Egret Engine(白鹭引擎)是一款免费开源的HTML5游戏引擎,使用Egret Engine可以快速开发基于HTML5的网页游戏,您不仅可以体验到开源免费游戏引擎产品,同时还能通过Egret相 ...

  9. Egret白鹭引擎初始介绍及简单应用

    白鹭简介    白鹭引擎是一套完整的H5游戏开发的解决方案,这个引擎中包含多个工具和项目,使用白鹭引擎可以轻松实现H5的游戏的开发. 使用EgretEngine开发的游戏可发布为HTML5版本,运行于 ...

最新文章

  1. 是把计算机分析和恢复力实测,土木工程测试试题.docx
  2. 中大型网站技术架构演变过程
  3. 1-Dimensional Heightfield Visibility Query
  4. 日期年月日的比较以及判断
  5. #翻译NO.4# --- Spring Integration Framework
  6. 关于tag,viewWithTag
  7. [机器学习-坑] error: Microsoft Visual C++ 14.0 is required
  8. 逐条驳斥天猫精灵抄袭说?百度钱晨解秘小度Play设计
  9. Android开发之重力传感器
  10. 速度更新!GoCD又曝仨洞,极易遭利用且结合利用可成供应链攻击的新跳板
  11. Javacript中(function(){})() 与 (function(){}()) 区别 {转}
  12. 推荐系统-Task01熟悉新闻推荐系统基本流程
  13. C#利用Process关闭所有的IE窗口
  14. java 简易扫雷_JAVA基础课程设计 简易扫雷
  15. IOS多线程之NSThread
  16. SSM+家装管理系统 毕业设计-附源码191452
  17. 【Unity Shader 中Pass相关介绍_第一篇】
  18. Excel快速下拉填充序列至10000行
  19. 2021-11-08FGUI 使用
  20. 如何做一个基于JAVA房产中介预约看房系统毕业设计毕设作品(springboot框架)

热门文章

  1. 医疗HIS管理系统短信接入流程
  2. 浙江高考600分计算机专业,理科600分的想学计算机可以报什么学校?
  3. 小程序scroll-view示例
  4. Speedtest 直装高级版 +支持多平台 —— 强悍网络速度测试工具!
  5. sichost.exe,winxphelp.exe,360up.exe,RavNT.exe,Counter.exe,login.jpg.exe等4
  6. 分析当下最流行的思维框架,思维模型。
  7. java_基础_遍历map删除元素_Java 遍历Map(包括集合)时,修改删除元素
  8. word中如何设置页码从任意页开始算起
  9. 让div水平居中的7种方法
  10. VAE+TSNE-mnist可视化项目