Skip to content

Instantly share code, notes, and snippets.

@nuintun
Last active May 29, 2025 07:43
Show Gist options
  • Save nuintun/f3b7d36bd8413c962a4637bb0d1dde8d to your computer and use it in GitHub Desktop.
Save nuintun/f3b7d36bd8413c962a4637bb0d1dde8d to your computer and use it in GitHub Desktop.
BigInt 和 Bytes 互转
/**
* @module bigint
*/
function getByteLength(value: bigint): number {
if (value === 0n || value === -1n) {
return 1;
}
if (value < 0n) {
value = ~value;
}
let bitLength = 0;
while (value > 0n) {
bitLength++;
value >>= 1n;
}
return Math.ceil(bitLength / 8) + 1;
}
export function bigIntToBytes(value: bigint, littleEndian: boolean = false): Uint8Array {
const byteLength = getByteLength(value);
const bytes = new Uint8Array(byteLength);
if (littleEndian) {
for (let offset = 0; offset < byteLength; offset++) {
const currentBitShift = offset * 8;
bytes[offset] = Number((value >> BigInt(currentBitShift)) & 0xffn);
}
} else {
const highestBitShift = (byteLength - 1) * 8;
for (let offset = 0; offset < byteLength; offset++) {
const currentBitShift = highestBitShift - offset * 8;
bytes[offset] = Number((value >> BigInt(currentBitShift)) & 0xffn);
}
}
return bytes;
}
export function bytesToBigInt(bytes: Uint8Array, littleEndian: boolean = false): bigint {
let value = 0n;
const { byteLength } = bytes;
if (byteLength > 0) {
const maxOffset = byteLength - 1;
const isNegative = (bytes[littleEndian ? maxOffset : 0] & 0x80) !== 0;
if (isNegative) {
for (let offset = 0; offset < byteLength; offset++) {
const byte = bytes[littleEndian ? maxOffset - offset : offset];
value = (value << 8n) | BigInt(byte ^ 0xff);
}
return ~value;
}
for (let offset = 0; offset < byteLength; offset++) {
const byte = bytes[littleEndian ? maxOffset - offset : offset];
value = (value << 8n) | BigInt(byte & 0xff);
}
return value;
}
return value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment