首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Endianness安全复制二进制数据

Endianness安全复制二进制数据
EN

Stack Overflow用户
提问于 2016-11-24 13:34:26
回答 2查看 255关注 0票数 0

我试图用ArrayBuffer操作二进制数据。如果原始ArrayBuffer如下所示:

代码语言:javascript
复制
var buffer = new ArrayBuffer(40);
var dv = new DataView(buffer);

var num = 0;
for(var i = 0; i < 40; i+=2) {
    dv.setUint16(i, num++);
}

ArrayBuffer的长度为20 Uint16Array。我想要额外的二进制数据,而不是附加数据。假设我想像这样在5个字节的Uint8前面加上:

代码语言:javascript
复制
ArrayBuffer[0] = 10;
ArrayBuffer[1] = 20;
ArrayBuffer[2] = 30;
ArrayBuffer[3] = 40;
ArrayBuffer[4] = 50;
ArrayBuffer[5 ~ 25] = Original Data

据我所知,在ArrayBuffer中没有前置的like方法,所以我自己做了。这不重要,但考虑到痴情真的让我发疯了。

前5个字节的数据是由我产生的,所以我可以手动设置endianness,但是原始数据来自外部,所以数据可以是Little Endian和Big。

我正在为Node.js和Web制作某种二进制数据模块,基本用法是使用该模块从Web浏览器中预置额外的二进制数据,浏览器将其发送到服务器,然后服务器也从该模块读取这些二进制数据,然后分割成预置和原始数据。

但问题是,如果浏览器,我指的是使用小终端的客户端计算机,而服务器使用大端,原始数据可能无法正确读取,因为它们具有不同的特性。

我将原始数据附加到像这样的新二进制数据中。新的二进制数据在0~5字节时有不同的5字节数据。所以我必须在5个字节偏移后写。

代码语言:javascript
复制
// write rest of data
var newBuffer = new ArrayBuffer(5 + origBuffer.byteLength);
var ndv = new DataView(newBuffer);
var dv = new DataView(origBuffer);    

for(var i = 0; i < origBuffer.byteLength; i++) {
    var offset = 5 + i;
    ndv.setUint8(offset, dv.getUint8(i));
}

在我的本地机器上进行测试是可以的,因为服务器和客户端都使用相同的cpu,但是在现实生活中,如果它们有不同的特性,这个模块将不能正常工作。

是否有一种使用ArrayBuffer & DataView复制二进制数据的安全方法?还是我应该忘了她的恩典?任何建议都会很感激的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-30 23:39:12

对于字节来说,这并不重要,因为它们没有endianess性,但是如果您获得的数据比字节(16/32位等)更宽,您就必须提前了解它,因为没有办法检测原始endianess (您可以根据数据进行一些猜测,但是.)。

在大多数情况下,字节流是按照所谓的网络顺序的,基本上是大端的,DataView默认的是什么。

但是,我建议在向客户端发送任何数据之前实现一个测试函数。例如,使用isLittleEndian()函数从客户端调用服务器,该函数触发服务器返回一个16位值,如0xff00。然后测试接收字节的顺序--类似于:

代码语言:javascript
复制
function isLittleEndian(callback) {  // callback as request will be async
  // get 0xff00 from server as 2 byte ArrayBuffer here somehow...
  var test = new Uint8Array(arraybufferFromServer);
  callback({isLittleEndian: !test[0]}); // will be 0x00ff as little-endian
}

然后,可以使用各种方法的小endian标志将结果与DataView一起使用。

请注意,这适用于数据流,而不一定适用于服务器的CPU体系结构/endian(小端服务器仍然可以(也很可能)以大端/网络顺序发送数据)。

票数 1
EN

Stack Overflow用户

发布于 2016-11-24 14:15:42

由于您使用的不是具有索引访问的Uint16Array,而是DataView及其 method,因此endianness始终默认为大端。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40787793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档