function intFromBytes( x ){
var val = 0;
for (var i = 0; i < x.length; ++i) {
val += x[i];
if (i < x.length-1) {
val = val << 8;
}
}
return val;
}
function getInt64Bytes( x ){
var bytes = [];
var i = 8;
do {
bytes[--i] = x & (255);
x = x>>8;
} while ( i )
return bytes;
}
我正在尝试将javascript编号转换为字节数组,然后返回到数字。但是,上述功能会产生非常大数量的错误输出。
var array = getInt64Bytes(23423423);
var value = intFromBytes(array);
console.log(value); //Prints 23423423 - correct
var array = getInt64Bytes(45035996273704);
var value = intFromBytes(array);
console.log(value); //Prints -1030792152 - incorrect
据我所知,javascript浮动是53
位,所以它不应该溢出? alert(Math.pow(2,53))
工作正常。
答案 0 :(得分:37)
使用Susanoh13提供的提示,这里有两个允许从/到ByteArray转换数字的函数:
longToByteArray = function(/*long*/long) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for ( var index = 0; index < byteArray.length; index ++ ) {
var byte = long & 0xff;
byteArray [ index ] = byte;
long = (long - byte) / 256 ;
}
return byteArray;
};
byteArrayToLong = function(/*byte[]*/byteArray) {
var value = 0;
for ( var i = byteArray.length - 1; i >= 0; i--) {
value = (value * 256) + byteArray[i];
}
return value;
};
答案 1 :(得分:13)
在JavaScript中,位移(>>
,<<
)始终在带符号的32位整数上执行。这会导致大量的范围溢出。
答案 2 :(得分:3)
执行位移与乘以2 ^(位数+ 1)相同,因此不必移位val = val<<8
位,而只需执行val = val*256
。看看是否有效。
答案 3 :(得分:3)
Brainfuck风格的Lodash版本。只有4 lulz!不要用它!
const uintToArray = (uint, size) => _.chunk(_.padStart(uint, size*2, 0).split(''), 2).map((a)=>parseInt(a[0]+a[1]))
答案 4 :(得分:2)
如果碰巧在Node.js上,Buffer
是处理Javascript / Typescript中任何字节数组/流的正确方法:
https://nodejs.org/api/buffer.html
尽管文档比较全面,但是如果链接404,Stack Overflow会在此处推荐代码段,因此,该文档中有几个最重要的代码示例:
// Creates a Buffer containing the UTF-8-encoded bytes for the string 'tést':
// [0x74, 0xc3, 0xa9, 0x73, 0x74] (in hexadecimal notation)
// [116, 195, 169, 115, 116] (in decimal notation)
const buf6 = Buffer.from('tést');
// Creates a Buffer containing the bytes [1, 2, 3].
const buf4 = Buffer.from([1, 2, 3]);
答案 5 :(得分:0)
<html>
<head>
<meta charset="utf-8">
<title>Uint32_To_Byte_Array</title>
<script>
function body_Add(Msg)
{
document.body.innerHTML = document.body.innerHTML + Msg;
}
class Byte
{
constructor(Value)
{
this.Number = new Uint8Array(1);
this.Number[0] = Value;
}
get Get()
{
return this.Number[0];
}
set Set(newValue)
{
this.Number[0] = newValue;
}
};
class Uint32
{
constructor(Value)
{
this.Number = new Uint32Array(1);
this.Number[0] = Value;
}
get Get()
{
return this.Number[0];
}
set Set(newValue)
{
this.Number[0] = newValue;
}
};
var Conversion =
{
Uint32_To_Byte_Array: function(Source_Num)
{
var Uint32_Num = new Uint32(Source_Num);
var Byte_Num = new Byte(0);
var Byte_Arr = new Uint8Array(4);
for (var i = 0; i < 4; i++)
{
if (Source_Num > 255)
{
Uint32_Num.Set = Source_Num / 256;
Byte_Num.Set = Source_Num - Uint32_Num.Get * 256;
}
else
{
Byte_Num.Set = Uint32_Num.Get;
Uint32_Num.Set = 0;
}
Byte_Arr[i] = Byte_Num.Get;
Source_Num = Uint32_Num.Get;
}
return(Byte_Arr);
},
Byte_Array_To_Uint32: function(Source_Byte_Array, Start_Position)
{
var Uint32_Num = new Uint32(0);
var Multiplier = 1;
for (let i = 0; i < 4; i++)
{
Uint32_Num.Set = Uint32_Num.Get + Source_Byte_Array[Start_Position + i] * Multiplier;
Multiplier = Multiplier * 256;
}
return (Uint32_Num.Get);
}
};
function Load_Page()
{
var Numbers = [0,1,257,4294967295];
Numbers.forEach(Convert);
function Convert(Item, Index)
{
var Uint32_Number = Item;
var Byte_Array = Conversion.Uint32_To_Byte_Array(Uint32_Number);
var Uint32_Number_Restored = Conversion.Byte_Array_To_Uint32(Byte_Array, 0);
body_Add("Conversion: Source number: " + Uint32_Number.toString() + ", Byte array: " + Byte_Array.toString() + ", Restored number: " + Uint32_Number_Restored.toString() + "<br>");
};
};
</script>
</head>
<body onload="Load_Page()">
</body>
答案 6 :(得分:0)
尝试
function getInt64Bytes(x) {
let y= x/2**32;
return [y,(y<<8),(y<<16),(y<<24), x,(x<<8),(x<<16),(x<<24)].map(z=> z>>>24)
}
function intFromBytes(byteArr) {
return byteArr.reduce((a,c,i)=> a+c*2**(56-i*8),0)
}
function getInt64Bytes(x) {
let y= x/2**32;
return [y,(y<<8),(y<<16),(y<<24), x,(x<<8),(x<<16),(x<<24)].map(z=> z>>>24)
}
function intFromBytes(byteArr) {
return byteArr.reduce((a,c,i)=> a+c*2**(56-i*8),0)
}
// TEST
let n= 40*2**40 + 245*2**32 + 194*2**24 + 143*2**16 + 92*2**8 + 40;
let b= getInt64Bytes(n);
let i = intFromBytes(b);
console.log(`number : ${n}`);
console.log(`int to bytes: [${b}]`);
console.log(`bytes to int: ${i}`);
答案 7 :(得分:0)
这行得通,
let buf;
if (num < 128)
{
buf = Buffer.from([num]);
}
else if (num < 256)
{
buf = Buffer.from([129, num]);
}
else if (num < 65536)
{
buf = Buffer.from([130, 256, num % 256]);
}
else if (num < 65536)
{
buf = Buffer.from([130, num / 256, num % 256]);
}
else if (num < 16777216)
{
buf = Buffer.from([131, num / 65536, num / 256, num % 256]);
}
console.log(buf.toString('hex'));