js xxtea 支持中文(转为byte数组与服务器交互)

js与服务器通过byte数组交互




        var login = function () {
            var data = xxtea_encrypt("aaa", 'caonima');
            var oReq = new XMLHttpRequest();

            // 方法一:参考https://www.jb51.net/article/92623.htm
            // oReq.responseType = "arraybuffer";
            // oReq.onload = function (oEvent) {
            //     console.log("oEvent-------" +JSON.stringify(oEvent));
            //     var arrayBuffer = oReq.response; // 注意:不是oReq.responseText
            //     console.log("arrayBuffer" + arrayBuffer);
            //     if (arrayBuffer) {
            //         var byteArray = new Uint8Array(arrayBuffer);
            //         console.log("arrayBuffer" + byteArray);
            //         var cao = xxtea_decrypt(byteArray, "caonima");
            //         console.log("binStr " + cao);
            //     }
            // };

            //方法二:参考 https://blog.csdn.net/github_37519401/article/details/78582885
            oReq.overrideMimeType('text/plain; charset=x-user-defined');//该行重写了默认的MIME类型,强制浏览器将该响应当成纯文本文件来对待, 使用一个用户自定义的字符集.
            oReq.onreadystatechange = function(e) {
                if (this.readyState == 4 && this.status == 200) {
                        var responseText = this.responseText;
                        console.log("responseText长度 " + responseText.length);
                        var array = new Uint8Array(responseText.length);
                        for (var i = 0, len = responseText.length; i < len; ++i) {
                            var c = responseText.charCodeAt(i);
                            var byte = c & 0xff; 
                            array[i] = byte;
                        }

                        console.log("bytearray " + array);
                        var cao = xxtea_decrypt(array, "caonima");
                        console.log("最终结果 " + cao);
                }
            };


            oReq.open("POST", 'http://qianliliang.com/account/account', true);
            oReq.send(data);
      }


    // 加密:得到的是byte数组
    // str是string, key也是string
    function xxtea_encrypt(str, key) {
        if (str == "") {
            return "";
        }

        if (typeof str === 'string') str = toBytes(str);
        if (typeof key === 'string') key = toBytes(key);
        if (str === undefined || str === null || str.length === 0) {
            return str;
        }
        var v= toUint32Array(str, true);
        var k =  toUint32Array(key, false);

        var n = v.length - 1;
     
        var z = v[n], y = v[0], delta = 0x9E3779B9;
        var mx, e, q = Math.floor(6 + 52 / (n + 1)), sum = 0;
        while (q-- > 0) {
            sum = sum + delta & 0xffffffff;
            e = sum >>> 2 & 3;
            for (var 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;
        }
        console.log("草拟吗" + v);
        // var str = long2str(v, false);
        var uint8Array = toUint8Array(v, false);
        console.log("草拟吗" + uint8Array);

        return uint8Array;
    }

    // 解密
    // byte数组, key是string
    function xxtea_decrypt(bytes, key) {

        var v = toUint32Array(bytes, false);
        var k = toUint32Array(toBytes(key), false);

        var n = v.length - 1;
     
        var z = v[n - 1], y = v[0], delta = 0x9E3779B9;
        var mx, e, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;
        while (sum != 0) {
            e = sum >>> 2 & 3;
            for (var 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 test= toUint8Array(v, true);
        //var test= new Array(97,98,99);
        return toString(test);
    }

    // byte数组转32位无符号数组
    function toUint32Array(bytes, includeLength) {
        var length = bytes.length;
        var n = length >> 2;
        if ((length & 3) !== 0) {
            ++n;
        }
        var v;
        if (includeLength) {
            v = new Array(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;
    }


    // 32位无符号整数型数组 转 byte数组
    function toUint8Array(v, includeLength) {
        var n;
        if (includeLength) {
            n = v[v.length - 1];
        } else {
            n = v.length << 2;
        }

        var result = new Uint8Array(n);
        for (var i = 0; i < n; i++) {
            result[i] =  v[i >> 2] >> ((i & 3) << 3);
        }
        return result;
    }

    // str转byte数组
    function 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');
            }
        }
    console.log("长度 " +length);
        return bytes.subarray(0, length);
    }

    function toShortString(bytes, n) {
        var charCodes = new Array(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.slice(0, i);//charCodes.subarray(0, i);
        }
        return String.fromCharCode.apply(String, charCodes);
    }

    function toLongString(bytes, n) {
        var buf = [];
        var charCodes = new Array(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.slice(0, i)));
        }
        return buf.join('');
    }

    function toString(bytes) {
        var n = bytes.length;
        if (n === 0) return '';
        return ((n < 100000) ? toShortString(bytes, n) : toLongString(bytes, n));
    }
    ```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值