浏览器从二进制字符串中读取整数
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
尚未得到完全支持。
例如我这里有这个字符串
'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 为其他一些迷失的灵魂。
值得一提的是
我只是以二进制形式发送我的二进制数据
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
尚未得到完全支持。