将字节数组转换为base128有效的JSON字符串

时间:2018-11-02 11:31:39

标签: javascript json

我想使用JSON发送大字节数组(我受到this question的启发),我希望使用base128编码(实际上可以产生有效的json字符串)来减少开销。但不幸的是,我无法找到一些在JS中进行转换的过程。我将发布程序作为对此问题的答案,但是可能是某人的程序更短,或者可能是在JSON中有效发送二进制数据的更好的主意。

1 个答案:

答案 0 :(得分:1)

ES6:

编码

let bytesToBase128 = (bytesArr) => {
    // 128 characters to encode as json-string
    let c= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz¼½ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" 
    let fbits=[]; 
    let bits = (n,b=8) => [...Array(b)].map((x,i)=>n>>i&1); 
    bytesArr.map(x=> fbits.push(...bits(x)));

    let fout=[]; 
    for(let i =0; i<fbits.length/7; i++) { 
        fout.push(parseInt(fbits.slice(i*7, i*7+7).reverse().join(''),2))  
    }; 

    return (fout.map(x => c[x])).join('');
}

// Example
// bytesToBase128([23, 45, 65, 129, 254, 42, 1, 255]) => "NÚ4AèßÊ0ÿ1"

解码

let base128ToBytes = (base128str) => {
    // 128 characters to encode as json-string
    let c= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz¼½ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" 

    dfout = base128str.split('').map(x=>c.indexOf(x));
    let dfbits = [];
    let bits = (n,b=8) => [...Array(b)].map((x,i)=>n>>i&1);
    dfout.map(x=> dfbits.push(...bits(x,7) ));

    let dfbytes=[]; 
    let m1 = dfbits.length%8 ? 1 : 0;
    for(let i =0; i<dfbits.length/8-m1; i++) { 
        dfbytes.push(parseInt(dfbits.slice(i*8, i*8+8).reverse().join(''),2))  
    }; 

    return dfbytes;
}

// Example
// base128ToBytes("NÚ4AèßÊ0ÿ1") => [23, 45, 65, 129, 254, 42, 1, 255]

我在这里嵌入了bits函数-here。这里的掩盖思想是将字节数组转换为位数组,然后将每个7位(值从0到127)作为字符编号i charakter list c。在解码时,我们将每个字符数更改为7位数字并创建数组,然后将这个数组的每个8位数据包都打包为字节。

要查看来自ASCI的字符并从中选择128个(任意),请在控制台中键入

[...Array(256)].map((x,i) => String.fromCharCode(i)).join('');

我尽量避免在! @ # $ % ' & ...等不同上下文中具有“特殊含义”的字符

这是working example(将Float32Array转换为json)。

在Chrome,Firefox和Safari上进行了测试

结论

在将bytes数组转换为base128字符串(有效json)之后,输出字符串小于输入数组的15%

更新

再挖掘一点,然后发现当我们发送代码大于128(¼½ÀÁÂÃÄ...)的字符时,chrome实际上发送了两个字符(字节),而不是一个:(-我在此进行了测试方式:在网址列 chrome:// net-internals /#events 中输入(并发送POST请求),然后在 URL_REQUEST> HTTP_STREAM_REQUEST> UPLOAD_DATA_STREAM_INIT> total_size 中看到当正文包含大于128的字符的女巫代码时,它的大小是原来的两倍。因此,实际上,发送此字符:(我们没有收益。对于base64字符串,我们没有观察到这种负面行为-但是我离开了此过程,因为它们可能被再用除了发送以外还有其他目的(例如,与base64相比,本地存储中存储二进制数据的更好替代方案-但是可能存在更好的方法...?)。 UPDATE 2019 here

相关问题