0

I want to encode and decode Bytes from an Uint8Array (or an ArrayBuffer) to/from a string in Base36. JavaScript has the toString and parseInt functions which both support base36 but I am not sure if first converting 8 Bytes to a 64 bit floating point is the right idea.

In JS one can encode a BigInt (a number of arbitrary length) in Base36. However the other direction does not work.

How can I do this?

Heretic Monkey
  • 11,078
  • 7
  • 55
  • 112
trizuz
  • 1
  • 2
  • Does this answer your question? [How do I convert a float to base36 in Python?](https://stackoverflow.com/questions/61205931/how-do-i-convert-a-float-to-base36-in-python) – Dhana D. Aug 15 '21 at 15:36
  • @DhanaD Encoding a single float in Base36 is easy in javascript. My question is if i first should convert my Byte Array to an Array of floats and then convert every float to Base36. I don't think I will be able to decode the string because the results are of different length. – trizuz Aug 15 '21 at 15:45
  • @DhanaD. Please refrain from attempting to close questions as duplicates of questions in another language. See [this meta question for the discussion](https://meta.stackoverflow.com/q/367501/215552). – Heretic Monkey Aug 15 '21 at 16:30

1 Answers1

0

I found the solution with the help of these two posts: Why JavaScript base-36 conversion appears to be ambiguous and How to go between JS BigInts and TypedArrays

function bigIntToBase36(num){
    return num.toString(36);
}

function base36ToBigInt(str){
    return [...str].reduce((acc,curr) => BigInt(parseInt(curr, 36)) + BigInt(36) * acc, 0n);
}

function bigIntToBuffer(bn) {
    let hex = BigInt(bn).toString(16);
    if (hex.length % 2) { hex = '0' + hex; }

    const len = hex.length / 2;
    const u8 = new Uint8Array(len);

    let i = 0;
    let j = 0;
    while (i < len) {
        u8[i] = parseInt(hex.slice(j, j+2), 16);
        i += 1;
        j += 2;
    }

    return u8;
}

function bufferToBigInt(buf) {
    const hex = [];
    const u8 = Uint8Array.from(buf);

    u8.forEach(function (i) {
        var h = i.toString(16);
        if (h.length % 2) { h = '0' + h; }
        hex.push(h);
    });

    return BigInt('0x' + hex.join(''));
}

const t1 = new Uint8Array([123, 51, 234, 234, 24, 124, 2, 125, 34, 255]);
console.log(t1);
const t2 = bigIntToBase36(bufferToBigInt(t1));
console.log(t2);
console.log(t2.length)
const t3 = bigIntToBuffer(base36ToBigInt(t2));
console.log(t3);
trizuz
  • 1
  • 2