简体   繁体   中英

how to convert javascript BigInt to Uint8Array with negative values considered

I have a java backend that's reading/writing arbitrary precision numbers with javascript front-end using bytes.

On Java side I just do:

new BigInteger("123").toByteArray()

The doc says:

Returns a byte array containing the two's-complement 
representation of this BigInteger.

On javascript side I need to read the bytes into javascript's BigInt, and vise versa.

I have the javascript reading the bytes into BigInt as bellow:

const hex = Buffer.from(bytes).toString('hex')
let big = BigInt('0x' + hex)
if (a[0] & 0x80) {
  const negative = BigInt('0x1' + '0'.repeat(hex.length))
  big -= negative
}

But converting BigInt to bytes seems to be very tricky. I looked around and found that other solutions all only cover positive numbers but not negative numbers

After digging around and understanding two's-complement representation, I'm answering my own question:

const big0 = BigInt(0)
const big1 = BigInt(1)
const big8 = BigInt(8)  

function bigToUint8Array(big: bigint) {
  if (big < big0) {
    // work out how long is the big int in bits and add 1
    const bits: bigint = (BigInt(big.toString(2).length) / big8 + big1) * big8  
    // create a BigInt that's 100000... of length of big + 1
    const prefix1: bigint = big1 << bits
    big += prefix1
  }
  let hex = big.toString(16)
  if (hex.length % 2) {
    hex = '0' + hex
  }
  const len = hex.length / 2
  const u8 = new Uint8Array(len)
  var i = 0
  var j = 0
  while (i < len) {
    u8[i] = parseInt(hex.slice(j, j + 2), 16)
    i += 1
    j += 2
  }
  return u8
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM