Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

bit manipulation - How to generate a fixed-length code from a set of integers of a specific bit count in JavaScript

Generate string from integer with arbitrary base in JavaScript received the following answer:

function parseInt(value, code) {
    return [...value].reduce((r, a) => r * code.length + code.indexOf(a), 0);
}

function toString(value, code) {
    var digit,
        radix= code.length,
        result = '';

    do {
        digit = value % radix;
        result = code[digit] + result;
        value = Math.floor(value / radix);
    } while (value)

    return result;
}

console.log(parseInt('dj', 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(toString(123, 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(parseInt('a', 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(toString(0, 'abcdefghijklmnopqrstuvwxyz0123456789+-'));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This really comes down to changing toString so that:

  • It only accepts a code that has a length of a power of 2
  • It pads the result to a given number of "digits" (characters)

The actual number of digits you would use for a 16 bit number depends on the size of the code. If the code has 16 characters, then it can cover for 4 bits, and so an output of 4 characters would be needed. If however the code has 4 characters, then the output would need 8 characters. You can have cases where the match is not exact, like when you would have a code with 8 characters. Then the output would need 6 characters.

Here I have highlighted the changes to the toString method. My personal preference is to also put the value as last parameter to toString.

function toString(digitCount, code, value) { // <-- add argument digitCount
    // Perform a sanity check: code must have a length that is power of 2
    if (Math.log2(code.length) % 1) throw "code size not power of 2: " + code.length;
    var digit,
        radix = code.length,
        result = '';

    do {
        digit = value % radix;
        result = code[digit] + result;
        value = Math.floor(value / radix);
    } while (value)

    return result.padStart(digitCount, code[0]); // Pad to the desired output size
}

console.log(toString(4, 'abcdefghijklmnop',    123));
console.log(toString(4, 'abcdefghijklmnop',      0));
console.log(toString(4, 'abcdefghijklmnop', 0xFFFF));

// You could define some more specific functions

const code8 = (code, value) => toString(Math.ceil(8 / Math.log2(code.length)), code, value);
const code16 = (code, value) => toString(Math.ceil(16 / Math.log2(code.length)), code, value);  

console.log(code16('abcdefghijklmnop',    123));
console.log(code16('abcdefghijklmnop',      0));
console.log(code16('abcdefghijklmnop', 0xFFFF));

console.log(code8('abcdefghijklmnop',  123));
console.log(code8('abcdefghijklmnop',    0));
console.log(code8('abcdefghijklmnop', 0xFF));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...