将javascript Integer转换为byte数组并返回

时间:2011-12-12 23:14:33

标签: javascript

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))工作正常。

8 个答案:

答案 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'));