Joe*_*ani 5 javascript integer bytearray bitconverter
如果我Uint8Array在JavaScript中有一个数组,我如何得到最后四个字节然后将其转换为int?使用C#我会做这样的事情:
int count = BitConverter.ToInt32(array, array.Length - 4);
Run Code Online (Sandbox Code Playgroud)
是否有使用JavaScript的不等效方法?
访问底层ArrayBuffer并TypedArray使用一小段字节创建一个新的:
var u8 = new Uint8Array([1,2,3,4,5,6]); // original array
var u32bytes = u8.buffer.slice(-4); // last four bytes as a new `ArrayBuffer`
var uint = new Uint32Array(u32bytes)[0];
Run Code Online (Sandbox Code Playgroud)
如果TypedArray没有覆盖整个缓冲区,你需要有点棘手,但不是很多:
var startbyte = u8.byteOffset + u8.byteLength - Uint32Array.BYTES_PER_ELEMENT;
var u32bytes = u8.buffer.slice(startbyte, startbyte + Uint32Array.BYTES_PER_ELEMENT);
Run Code Online (Sandbox Code Playgroud)
这适用于两种情况.
如果你想要的字节适合数据类型的底层缓冲区的对齐边界(例如,你想要底层缓冲区的字节4-8的32位值),你可以避免复制字节,slice()只提供一个byteoffset视图构造函数,如@ Bergi的答案.
下面是一个非常轻微测试的函数,它应该得到你想要的任何偏移量的标量值.如果可能的话,它将避免复制.
function InvalidArgument(msg) {
this.message = msg | null;
}
function scalarValue(buf_or_view, byteOffset, type) {
var buffer, bufslice, view, sliceLength = type.BYTES_PER_ELEMENT;
if (buf_or_view instanceof ArrayBuffer) {
buffer = buf_or_view;
if (byteOffset < 0) {
byteOffset = buffer.byteLength - byteOffset;
}
} else if (buf_or_view.buffer instanceof ArrayBuffer) {
view = buf_or_view;
buffer = view.buffer;
if (byteOffset < 0) {
byteOffset = view.byteOffset + view.byteLength + byteOffset;
} else {
byteOffset = view.byteOffset + byteOffset;
}
return scalarValue(buffer, view.byteOffset + byteOffset, type);
} else {
throw new InvalidArgument('buf_or_view must be ArrayBuffer or have a .buffer property');
}
// assert buffer instanceof ArrayBuffer
// assert byteOffset > 0
// assert byteOffset relative to entire buffer
try {
// try in-place first
// only works if byteOffset % slicelength === 0
return (new type(buffer, byteOffset, 1))[0]
} catch (e) {
// if this doesn't work, we need to copy the bytes (slice them out)
bufslice = buffer.slice(byteOffset, byteOffset + sliceLength);
return (new type(bufslice, 0, 1))[0]
}
}
Run Code Online (Sandbox Code Playgroud)
你会像这样使用它:
// positive or negative byte offset
// relative to beginning or end *of a view*
100992003 === scalarValueAs(u8, -4, Uint32Array)
// positive or negative byte offset
// relative to the beginning or end *of a buffer*
100992003 === scalarValue(u8.buffer, -4, Uint32Array)
Run Code Online (Sandbox Code Playgroud)
如今,如果您可以使用IE 11+ / Chrome 49+ / Firefox 50+,那么您可以使用DataView让您的生活几乎像 C# 一样轻松:
var u8array = new Uint8Array([0xFF, 0xFF, 0xFF, 0xFF]); // -1
var view = new DataView(u8array.buffer)
console.log("result:" + view.getInt32());
Run Code Online (Sandbox Code Playgroud)
在这里测试: https: //jsfiddle.net/3udtek18/1/
你有一个例子吗?我认为这样做会:
var result = ((array[array.length - 1]) |
(array[array.length - 2] << 8) |
(array[array.length - 3] << 16) |
(array[array.length - 4] << 24));
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,其他答案没有使用本机 Buffer 对象,该对象在一个简单的本机库中提供了很多此类工具。这个库可能没有广泛用于位打包/解包,只是因为人们不想在这里检查,而且我也花了一段时间才找到它,但它是在 nodejs/javascript/ 中进行位打包/解包的正确工具打字稿。
你可以像这样使用它:
// Create a simple array with 5 elements. We'll pop the last 4 and you should expect the end value to be 1 because this is a little-endian array with all zeros other than the 1 in the littlest(?)-endian
const array = [0, 1, 0, 0, 0]
// get the last 4 elements of your array and convert it to a Buffer
const buffer = Buffer.from(array.slice(-4));
// Use the native Buffer type to read the object as an (U) unsigned (LE) little-endian 32 (32 bits) integer
const value = Buffer.readUInt32LE();
Run Code Online (Sandbox Code Playgroud)
或者,更简洁地说:
const value = Buffer.from(array.slice(-4)).readUInt32LE();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13001 次 |
| 最近记录: |