xealot
xealot

Reputation: 23

Reading variable length bits from a binary string

Im new to javascript and node.js, I have a base64 encoded string of data that I need to parse several values from which are of various bit lengths.

I figured I would start by using the Buffer object to read the b64 string but from there I am completely lost.

The data are a series of unsigned integers, The format is something akin to this: Header:

8 bits - uint  
3 bits - uint  
2 bits - uint  
3 bits - unused padding  
6 bits - uint

After that there are recurring sections of either 23 bit or 13 bit length of data each with a couple of fields I need to extract.

An example of a 23 bit section:

3 bit - uint  
10 bit - uint  
10 bit - uint  

My question is this, What is the best way to take an arbitrary number of bits and put the resulting value in a separate uint? Note that some of the values are multi-byte (> 8 bits) so I cant step byte for byte.

I apologize if my explanation is kind of vague but hopefully it will suffice.

Upvotes: 2

Views: 1337

Answers (1)

jJ'
jJ'

Reputation: 3078

One simple way to read any amount of bits is e.g.

function bufferBitReader(buffer) {
    var bitPos = 0;

    function readOneBit() {
        var offset = Math.floor(bitPos / 8),
            shift = 7 - bitPos % 8;
        bitPos += 1;
        return (buffer[offset] >> shift) & 1;
    }

    function readBits(n) {
        var i, value = 0;
        for (i = 0; i < n; i += 1) {
            value = value << 1 | readOneBit();
        }
        return value;
    }

    function isEnd() {
        return Math.floor(bitPos / 8) >= buffer.length;
    }

    return {
        readOneBit: readOneBit,
        readBits: readBits,
        isEnd: isEnd
    };
}

You just take your but buffer and initialize the reader by

var bitReader = bufferBitReader(buffer);

Then you can read any number of bits by calling

bitReader.readBits(8);
bitReader.readBits(3);
bitReader.readBits(2);
...

You can test whether you already read all bits by

bitReader.isEnd()

One thing to make sure is the actual order of bit that is expected... some 'bit streams' are expected to get bits from the least significant to the most significant.. this code expects the opposite that the first bit you read is the most significant of the first byte...

Upvotes: 4

Related Questions