浏览器从二进制字符串中读取整数

Browser read integer from binary string

例如我这里有这个字符串

'x���'

根据您使用的设备,您可能看不到。这是我使用 Node

生成的编码为 32 位有符号大端整数的数字 2024000250
let buffer = new Buffer(4);
b.writeInt32BE(2024000250).toString();

我在客户端收到了有问题的 4 个字节,但我似乎找不到如何将它们变回整数...

我在这里可能完全错了。但据我所知,unicode 字符可以在 2-4 个字节之间。当您将二进制数据作为文本传输到客户端时,您可能会破坏此信息,因为客户端会将它们解释为 unicode。

如果我要在客户端将该文本转换为 blob:

var b = new Blob(['x���'],{type:"application/octet-stream"});
b.size; //10 

如你所见,我收到了 10 个字节,这是错误的,应该是 4 个。

您可以直接将数据作为二进制字符串传输,因为您在服务器端使用 Node:

function createBuffer(v){
    var b = new ArrayBuffer(4),
        vw = new DataView(b);
    vw.setInt32(0,v);
    return b;
}

这将创建您的缓冲区,现在您不能直接将其发送给客户端,或者将其表示为 json 或直接作为二进制字符串。要将其表示为二进制,您不需要上述功能,您可以这样做:

("0".repeat(32) + (2024000250).toString(2)).slice(-32); //"01111000101000111100101011111010"

如果你想要json,你可以这样做:

function convertBuffToBinaryStr(buff){
    var res = [],
        l = buff.byteLength,
        v = new DataView(buff);
    for (var i = 0; i < l; ++i){
        res.push(v.getUint8(i));
    }
    return JSON.stringify(res);
}

现在尝试查看输出结果:

convertBuffToBinaryStr(createBuffer(2024000250)); //"[120,163,202,250]"

回到客户端你必须解释这个:

function interpret(json){
    json = JSON.parse(json);
    return parseInt(json.map((d)=>("0".repeat(8) + d.toString(2)).slice(-8)).join(""),2);
}

现在尝试:

interpret("[120,163,202,250]"); //2024000250

注意:对于您的解释函数,您必须使用 dataView 来设置 Uint8 并在最后使用 getInt32,因为您使用的是有符号整数,以上内容不适用于所有情况。

好吧,我终于抽出时间让它工作了。

这不是我一开始的想法,但我只是想 post 为其他一些迷失的灵魂。

值得一提的是 contains most of the necessary information but is trying to satisfy the XY problem 我的问题最终是。

我只是以二进制形式发送我的二进制数据

let buffer = new Buffer(4);
buffer.writeInt32BE(2024000250);

// websocket connection
connection.send(buffer);

然后在浏览器中

// message listener
let reader = new FileReader();
reader.addEventListener('loadend', () => {
  let view = new DataView(reader.result);

  // there goes the precious data
  console.log(view.getInt32());
});
reader.readAsArrayBuffer(message.data);

老实说,这让我的呕吐反射很痒。为什么我要使用文件 reader 从二进制消息中获取一些数据?很有可能存在更好的方法,如果是这样,请添加到此答案中。

我发现的其他方法是 fetch API,它在黑客评级方面并不比文件 reader 好,Blob.prototype.arrayBuffer 尚未得到完全支持。