今天遇到一个RN传值的问题。

Native代理网络请求的情况下,如果是PB请求,后台返回的数据是一个byte[]数组。

但是RN数据传送只能传String类型的。

可以通过fastJson装成Json字符串,转换过程中,会自动把byte[]类型的value转成base64字符串。

RN页面端接收到数据之后,需要将数据进行PB解析,PB解析需要一个byte[]类型的数据(JS里是Uint8Array)。

所以第一步要将base64字符串转换成byte[]数组。

这里给出几个base64与byte数组互转的方法,供大家参考。

一、base64字符串转byte[]数组

方法一:window.atob()

        //base64转字节
    function _base64ToArrayBuffer(base64) {
        var binary_string = window.atob(base64);//解码使用base64编码的字符串
        var len = binary_string.length;            //获取长度
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++) {
            bytes[i] = binary_string.charCodeAt(i);
        }
        console.log(bytes)     //打印解析出来的byte
        return bytes.buffer;
    }
    _base64ToArrayBuffer("CgRTMDAxEgRDSDAxHQjMBkMlsp0XwA==")

方法二:原生JavaScript代码

将base64转换成byte数组再转换成字符串

var BASE64B = [62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51]; //'A'=65,'a'=97,'0'=48,'+'=43,'/'=47 统一减43

//将base64转换成byte数组再转换成字符串
function decode(params,ascii) {
     if (params == null) return null;
     if (typeof params === "string") params = stringToBytes(params,ascii); //该方法只适用于utf-8编码和ascii编码
     if (params.length%4 != 0) return null;
     var length = params.length/4*3;if (params[params.length-2] == 61) length -= 2; else if (params[params.length-1] == 61) length -= 1;
     var result = new Array();
     var index = 0;
     for (var i=0;i<params.length-4;i+=4) {
         var bits = (BASE64B[params[i]-43] & 0xff) << 18 | (BASE64B[params[i+1]-43] & 0xff) << 12 | (BASE64B[params[i+2]-43] & 0xff) << 6 | (BASE64B[params[i+3]-43] & 0xff); //通过BASE64B[params[i]-43]将原始数值进行还原,然后再向左移位
         result[index++] = ((bits >>> 16) & 0xff); //&0xff表示保留8位数(类似求余),>>表示向右移多少位,低位会被丢弃,高位补0(无符号)或1(有符号),>>>表示向右移多少位,高位补0(无符号)
         result[index++] = ((bits >>> 8) & 0xff);
         result[index++] = (bits & 0xff);
     }
     if (params[params.length-2] == 61) {
         var bits = (BASE64B[params[params.length-4]-43] & 0xff) << 6 | (BASE64B[params[params.length-3]-43] & 0xff);
         result[index] = ((bits >>> 4) & 0xff);
     } else if (params[params.length-1] == 61) {
         var bits = (BASE64B[params[params.length-4]-43] & 0xff) << 12 | (BASE64B[params[params.length-3]-43] & 0xff) << 6 | (BASE64B[params[params.length-2]-43] & 0xff);
         result[index++] = ((bits >>> 10) & 0xff);
         result[index] = ((bits >>> 2) & 0xff);
     } else {
         var bits = (BASE64B[params[params.length-4]-43] & 0xff) << 18 | (BASE64B[params[params.length-3]-43] & 0xff) << 12 | (BASE64B[params[params.length-2]-43] & 0xff) << 6 | (BASE64B[params[params.length-1]-43] & 0xff);
         result[index++] = ((bits >>> 16) & 0xff);
         result[index++] = ((bits >>> 8) & 0xff);
         result[index] = (bits & 0xff);
     }
     return bytesToString(result,ascii);
}

二、byte[]数组转base64字符串

方法一:window.btoa()

  var arry  = [-1, -40, -1, -32, 0, 16, 74, 70, 73, 70, 0, 1, 2, 0, 0, 1, 0, 1, 0, 0, -1, -37, 0, 67, 0, 8, 6, 6, 7, 6, 5, 8, 7, 7, 7, 9, 9, 8, 10, 12, 20, 13, 12, 11, 11, 12, 25, 18, 19, 15, 20, 29, 26, 31, 30, 29, 26, 28, 28, 32, 36, 46, 39, 32, 34, -39];
    var str12 = arrayBufferToBase64(arry);//转换字符串
    console.log(str12);
    var outputImg = document.createElement('img');
    outputImg.src = 'data:image/png;base64,'+str12;
    // // append it to your page
    document.body.appendChild(outputImg);
    console.log(outputImg);
    function arrayBufferToBase64( buffer ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return window.btoa( binary );
    }

方法二:原生JavaScript代码

将byte数组(或字符串)转换成base64

var BASE64C = [65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47];
function encode(params,ascii) { //将byte数组(或字符串)转换成base64
     if (params == null) return null;
     if (typeof params === "string") params = stringToBytes(params,ascii); //该方法只适用于utf-8编码和ascii编码
     var result = new Array(); //每3个字节一组,重组为4个字节一组
     var index = 0;
     for (var i=0;i<parseInt(params.length/3)*3;i+=3) { //除3取整再乘3可以取到最后面的3的倍数个
         var bits = (params[i] & 0xff) << 16 | (params[i+1] & 0xff) << 8 | (params[i+2] & 0xff); //&0xff表示由byte转int,<<表示向左移多少位,高位会被丢弃,低位会补0
         result[index++] = BASE64C[(bits >>> 18) & 0x3f]; //&0x3f表示保留6位数(类似对64求余),>>表示向右移多少位,低位会被丢弃,高位补0(无符号)或1(有符号),>>>表示向右移多少位,高位补0(无符号)
         result[index++] = BASE64C[(bits >>> 12) & 0x3f];
         result[index++] = BASE64C[(bits >>> 6) & 0x3f];
         result[index++] = BASE64C[bits & 0x3f];
     }
     if (params.length%3 == 1) { //多余1个加两个=号
         var bits = (params[params.length-1] & 0xff) << 4;
         result[index++] = BASE64C[(bits >>> 6) & 0x3f];
         result[index++] = BASE64C[bits & 0x3f];
         result[index++] = 61; //stringToBytes('=')
         result[index] = 61;
     } else if (params.length%3 == 2) { //多余2个加一个=号
         var bits = (params[params.length-2] & 0xff) << 10 | (params[params.length-1] & 0xff) << 2;
         result[index++] = BASE64C[(bits >>> 12) & 0x3f];
         result[index++] = BASE64C[(bits >>> 6) & 0x3f];
         result[index++] = BASE64C[bits & 0x3f];
         result[index] = 61;
     }
     return bytesToString(result);
}

工具方法

上述JS转换代码中用到的string转换工具方法:


function stringToBytes(param,ascii) { //该方法只适用于utf-8编码和ascii编码(适用于生成文件),参数为string
     var bytes = new Array();
     if (ascii) {
         for (var i=0;i<param.length;i++) {
             bytes.push(param.charCodeAt(i));
         }
         return bytes;
     }
     for (var i=0;i<param.length;i++) {
         var c = param.charCodeAt(i);
         if (c == 0) { //兼容ascii编码向utf8转码,一般用不到
             bytes.push(0xe3); //0xe3=227
             bytes.push(0x84); //0x84=132
             bytes.push(0x80); //0x80=128
         } else if (c < 0x80) { //c < 128,首位为0,剩余7位
             bytes.push(c);
         } else if (c < 0x100) { //c < 256,兼容ascii编码向utf8转码,一般用不到
             bytes.push(0xc2); //0xc2=194
             bytes.push(c);
         } else if (c < 0x800) { //c < 2048,首位为110,表示该起始字节有1个后续字节,剩余5位
             bytes.push(((c >> 6) & 0x1f) | 0xc0); //0xC0=11000000,&0x1f表示取低5位(高位补0)
             bytes.push((c & 0x3f) | 0x80); //0x80=10000000,&0x3f表示取低6位(对64求余)
         } else if (c < 0x10000) { //c < 65536,首位为1110,表示该起始字节有2个后续字节,剩余4位
             bytes.push(((c >> 12) & 0x0f) | 0xe0); //0xE0=11100000,&0x0f表示取低4位(对16求余,高位补0)
             bytes.push(((c >> 6) & 0x3f) | 0x80);
             bytes.push((c & 0x3f) | 0x80);
         } else if (c < 0x10ffff) { //c < 2097152,首位为11110,表示该起始字节有3个后续字节,剩余3位
             bytes.push(((c >> 18) & 0x07) | 0xf0); //0xF0=11110000,&0x07表示取低3位(高位补0)
             bytes.push(((c >> 12) & 0x3f) | 0x80);
             bytes.push(((c >> 6) & 0x3f) | 0x80);
             bytes.push((c & 0x3f) | 0x80);
         } else return null; //超过0x10ffff,属于不合法字符
     }
     return bytes;
}
function bytesToString(params,ascii) { //该方法只适用于utf-8编码和ascii编码,参数为byte数组
     var result = "";
     if (ascii) {
         for (var i=0;i<params.length;i++) {
             result += String.fromCharCode(params[i]);
         }
         return result;
     }
     for (var i=0;i<params.length;i++) {
         if (params[i] >= 0xf8) { //超过0xf8=11111000,属于不合法字符
             result += String.fromCharCode(params[i]);
         } else if (params[i] >= 0xf0) { //0xf0=11110000,表示该起始字节有3个后续字节
             var bits = (params[i] & 0x07) << 18 | (params[i+1] & 0x3f) << 12 | (params[i+2] & 0x3f) << 6 | (params[i+3] & 0x3f);
             result += String.fromCharCode(bits);
             i += 3;
         } else if (params[i] >= 0xe0) { //0xe0=11100000,表示该起始字节有2个后续字节
             var bits = (params[i] & 0x0f) << 12 | (params[i+1] & 0x3f) << 6 | (params[i+2] & 0x3f);
             result += String.fromCharCode(bits);
             i += 2;
         } else if (params[i] >= 0xc0) { //0xc0=11000000,表示该起始字节有1个后续字节
             var bits = (params[i] & 0x1f) << 6 | (params[i+1] & 0x3f);
             result += String.fromCharCode(bits);
             i++;
         } else { //[227,132,128],[194,128]的情形已经融入到上面的判断语句中
             result += String.fromCharCode(params[i]);
         }
     }
     return result;
}

参考