2

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.

2
  • The hard part is not the fact you are having multi-byte values, but you are having values smaller than bytes! You sure you need that? Commented Sep 13, 2014 at 12:50
  • Unfortunately I have no choice in the matter as the string isnt generated by me. Commented Sep 16, 2014 at 17:11

1 Answer 1

4

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...

Sign up to request clarification or add additional context in comments.

1 Comment

Nice! I was thinking along those lines, but this is so clean and well made. Saved me some time – thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.