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.