XXTea加密 c++ 与 js 互相加解密

本文介绍了如何在服务器端使用C++实现XXTea加密算法,并在客户端利用JavaScript进行相同算法的加密,以实现跨平台的数据安全传输。通过base64编码进一步处理加密结果,确保数据的完整性和保密性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于加密功能,客户端使用的是creator  用js开发的,服务器端用lua做的
  • 要做加密功能: 1.利用c++绑定调用c++实现加密, 
                            好处:调用同一种方法,一次实现
                            坏处:c++绑定只能用在原生系统,如果是浏览器端将无法使用加密功能 
                      2.各自实现同一种算法
                            好处:各自实现,自己可以用任何方式实现
                            坏处:需要做到互相可以加解密
  • 本次选择第二种方法:服务器用c++ 实现XXTea加密算法,客户端用js实现XXtea加密算法
            

            过程: 客户端: XXTea加密 ----> base64编码   -----》send到服务器 -----》服务器先base64解码 -----》XXtea解密 ---->得到原始数据

               base64编码是为了将加密过后的不可见的字符转化为可见的字符串 再发送 (不然服务器接收不到...)

客户端代码: 
var TestXXTea = cc.Class({
    extends: cc.Component,
    statics: {
        keyString: "]\743f8/hr34hLuH",  //xxtea密钥 一般16位(也可以不是16位)
        xxtea_encrypt: function (str) {
            if (str == "") {
                return "";
            }
            str = utf16ToUtf8(str); //如果是中文解析可能会出问题,加密之前先转化为utf8格式
            var v = str2long(str, true);
            var k = str2long(this.keyString, false);
            if (k.length < 4) {
                k.length = 4;
            }
            var n = v.length - 1;
            var z = v[n], y = v[0], delta = 0x9E3779B9;
            var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = 0;
            while (0 < q--) {
                sum = sum + delta & 0xffffffff;
                e = sum >>> 2 & 3;
                for (p = 0; p < n; p++) {
                    y = v[p + 1];
                    mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                    z = v[p] = v[p] + mx & 0xffffffff;
                }
                y = v[0];
                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                z = v[n] = v[n] + mx & 0xffffffff;
            }
            str = long2str(v,false);
            return encode_base64(str);//加密过后用base64编码
        },

        xxtea_decrypt: function (str) {
            if (str == "") {
                return "";
            }
            str = decode_base64(str)
            var v = str2long(str, false);
            var k = str2long(this.keyString, false);
            if (k.length < 4) {
                k.length = 4;
            }
            var n = v.length - 1;
            var z = v[n], y = v[0], delta = 0x9E3779B9;
            var mx, e, p, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;
            while (sum != 0) {
                e = sum >>> 2 & 3;
                for (p = n; p > 0; p--) {
                    z = v[p - 1];
                    mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                    y = v[p] = v[p] - mx & 0xffffffff;
                }
                z = v[n];
                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                y = v[0] = v[0] - mx & 0xffffffff;
                sum = sum - delta & 0xffffffff;
            }
            var result = long2str(v,true);
            result = utf8ToUtf16(result);
            return result;
        },
    },
});

function utf16ToUtf8(str) { //utf16转化utf8 解决中文乱码问题 
    var out, i, len, c;
    out = "";
    len = str.length;
    for (i = 0; i < len; i++) {
        c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) {
            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
            out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        } else {
            out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        }
    }
    return out;
}

function utf8ToUtf16(str) {
    var out, i, len, c;
    var char2, char3;
    out = "";
    len = str.length;
    i = 0;
    while (i < len) {
        c = str.charCodeAt(i++); switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += str.charAt(i - 1);
                break;
            case 12: case 13:
                // 110x xxxx   10xx xxxx
                char2 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx  10xx xxxx  10xx xxxx
                char2 = str.charCodeAt(i++);
                char3 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }
    return out;
}

function long2str(v, w) {  //解密过程中将一个32位 数据转换成4个8位 的数据
    var vl = v.length;
    var n = (vl - 1) << 2;
    if (w) {
        var m = v[vl - 1];
        if ((m < n - 3) || (m > n)) return null;
        n = m;
    }
    for (var i = 0; i < vl; i++) {
        v[i] = String.fromCharCode(v[i] & 0xff,
            v[i] >> 8 & 0xff,
            v[i] >> 16 & 0xff,
            v[i] >> 24 & 0xff);
    }
    if (w) {
        return v.join('').substring(0, n);
    }
    else {
        return v.join('');
    }
}

function str2long(s, w) { //加密过程中将4个8位的数据转化成一个32位的数据
    var len = s.length;
    var v = [];
    for (var i = 0; i < len; i += 4) {
        v[i >> 2] = s.charCodeAt(i)
            | s.charCodeAt(i + 1) << 8
            | s.charCodeAt(i + 2) << 16
            | s.charCodeAt(i + 3) << 24;
    }
    if (w) {
        v[v.length] = len;
    }
    return v;
}

function encode_base64(input) {  //base64 编码 
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 
    var output = ""; 
    var chr1, chr2, chr3 = ""; 
    var enc1, enc2, enc3, enc4 = ""; 
    var i = 0;
    do { 
        chr1 = input.charCodeAt(i++); 
        chr2 = input.charCodeAt(i++); 
        chr3 = input.charCodeAt(i++);

        enc1 = chr1 >> 2; 
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 
        enc4 = chr3 & 63;

        if (isNaN(chr2)) { 
            enc3 = enc4 = 64; 
        } else if (isNaN(chr3)) { 
            enc4 = 64; 
        }

        output = output + 
           keyStr.charAt(enc1) + 
           keyStr.charAt(enc2) + 
           keyStr.charAt(enc3) + 
           keyStr.charAt(enc4); 
        chr1 = chr2 = chr3 = ""; 
        enc1 = enc2 = enc3 = enc4 = ""; 
    } while (i < input.length);

    return output; 
}


function decode_base64(input) { //base64解码 
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 
    var output = ""; 
    var chr1, chr2, chr3 = ""; 
    var enc1, enc2, enc3, enc4 = ""; 
    var i = 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值