JavaScript에 Uint8Array
배열이있는 경우 어떻게 마지막 4 바이트를 가져 와서 int로 변환 할 수 있습니까? C#을 사용하면 다음과 같이 할 수 있습니다.배열의 마지막 4 바이트를 정수로 변환하는 방법?
int count = BitConverter.ToInt32(array, array.Length - 4);
JavaScript를 사용하여 이와 다른 방법이 있습니까?
JavaScript에 Uint8Array
배열이있는 경우 어떻게 마지막 4 바이트를 가져 와서 int로 변환 할 수 있습니까? C#을 사용하면 다음과 같이 할 수 있습니다.배열의 마지막 4 바이트를 정수로 변환하는 방법?
int count = BitConverter.ToInt32(array, array.Length - 4);
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];
TypedArray
커버되지 않으면 전체 버퍼는 약간 복잡 할 뿐이지 만 약간은 복잡해야합니다.
var startbyte = u8.byteOffset + u8.byteLength - Uint32Array.BYTES_PER_ELEMENT;
var u32bytes = u8.buffer.slice(startbyte, startbyte + Uint32Array.BYTES_PER_ELEMENT);
두 경우 모두 작동합니다.
데이터 유형에 대한 기본 버퍼의 정렬 경계에 맞게 원하는 바이트가있는 경우 (예 : 기본 버퍼의 4-8 바이트의 32 비트 값을 원할 경우) slice()
으로 바이트 복사를 피할 수 있습니다 @ Bergi의 대답처럼 view 생성자에 byteoffset을 제공하면됩니다.
다음은 원하는 모든 오프셋의 스칼라 값을 가져야하는 매우 가볍게 테스트 된 함수입니다. 가능한 경우 복사하지 않습니다.
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]
}
}
이처럼 사용합니다 :
// 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)
+1, 매우 좋습니다. 그러나 'u8'이 버퍼에 오프셋이있는보기 인 경우 특수하게 처리해야합니다. – Bergi
예가 있습니까? 나는 이것을 할 것이라고 생각한다 :
var result = ((array[array.length - 1]) |
(array[array.length - 2] << 8) |
(array[array.length - 3] << 16) |
(array[array.length - 4] << 24));
'[255,255,255,255]'를 사용하면 어떤 이유로이 코드를 사용하여'-1'이됩니다. – Jespertheend
@Jespertheend 서명이 '-1'인 결과입니다. 결과를 부호없는 값 ('4294967295')으로 변환하려면 부호없는 오른쪽 시프트 연산자'>>> 0'을 추가하십시오. – SammieFox
흠, 그건 의미가 있습니다. – Jespertheend
조금 우아하지만, 수동으로 엔디안을 기반으로 할 수 있다면.
리틀 엔디안 :
var count = 0;
// assuming the array has at least four elements
for(var i = array.length - 1; i >= array.length - 4; i--)
{
count = count << 8 + array[i];
}
빅 엔디안 :이 다른 데이터로 확장 할 수
var count = 0;
// assuming the array has at least four elements
for(var i = array.length - 4; i <= array.length - 1 ; i++)
{
count = count << 8 + array[i];
}
는
편집 길이 : 내 오타
은'.length'가 아니어야합니다.'.Length' – 0x499602D2
을 지적 데이비드 덕분에 Uint32Array
를 만드는 것이 더 효율적이어야합니다. 523,210 동일한 ArrayBuffer에 직접 32- 비트 수에 :
var uint8array = new Uint8Array([1,2,3,4,5,6,7,8]);
var uint32array = new Uint32Array(
uint8array.buffer,
uint8array.byteOffset + uint8array.byteLength - 4,
1 // 4Bytes long
);
return uint32array[0];
두 번째 인수가 새로운 뷰의 길이의 배수가 아니면 같은 버퍼에 다른 유형의 새로운 뷰를 생성 할 수 없습니다. 예 : 8 바이트 버퍼에서 이것은 임의의 제약처럼 보이더라도 실패합니다 :'new Uint32Array (buffer, 2, 1)' –
@FrancisAvila : 힌트를 주셔서 감사합니다 .4Byte가 아닌 다중 버퍼가 필요한 경우 그걸 썰어. 위의 코드에서 코드를 수정했지만, 32 비트를 얻기 위해 byteLength에서 * 4 *를 뺄 필요가 있다는 사실을 잊어 버렸습니다. -/ – Bergi
var a = Uint8Array(6)
a.set([1,2,8,0,0,1])
i1 = a[a.length-4];
i2 = a[a.length-3];
i3 = a[a.length-2];
i4 = a[a.length-1];
console.log(i1<<24 | i2<<16 | i3<<8 | i4);
을 요즘 당신이 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());
여기에서 테스트 : https://jsfiddle.net/3udtek18/1/
@ cIph3r : [예] (https : //developer.mozilla.(Chrome 및 Safari, Opera, IE10 및 Android) (http :// ko/org/ko-ko/docs/JavaScript/Typed_arrays/Uint8Array) – Bergi
@Bergi 괜찮 았지만 firefox – cIph3r
@ clph3r, /caniuse.com/#feat=typedarrays) .... –