Question

I am trying to make a code that read blocks of 17 bits from a file and I have no idea of how to get this done, I mean that I will have any file and need to read the next 17 bits to apply a crc algorithm

Was it helpful?

Solution

I felt like programming something this afternoon.

The class BitReader below allows you to either read at most 8 bits at a time through the readBits method, or 17 bits in one go through the readBits17 method.

Source code

public class BitReader {
    private static final int[] MASK = new int[16];
    static {
        for (int i = 0; i < 16; i++) {
            MASK[i] = (1 << i) - 1;
        }
    }

    private InputStream in;

    private int bitsLeft;

    private int bitBuffer;

    public BitReader(InputStream in) {
        this.in = in;
    }

    /**
     * Reads at most 8 bits from the InputStream.
     * 
     * @param bits
     *            between 1 and 8 (inclusive)
     */
    public int readBits(int bits) throws IOException {
        if (bits < 1 && bits > 8)
            throw new IllegalArgumentException("bits");
        if (bits > bitsLeft) {
            int r = in.read();
            if (r == -1) {
                throw new EOFException();
            }
            bitsLeft += 8;
            bitBuffer = (bitBuffer << 8) | r;
        }
        int result = bitBuffer >> (bitsLeft - bits);
        bitsLeft -= bits;
        bitBuffer &= MASK[bitsLeft];
        return result;
    }

    public int readBits17() throws IOException {
        return readBits(8) << 9 | readBits(8) << 1 | readBits(1);
    }
}

The class Test just shows how to use BitReader.

public class Test {
    public static void main(String[] args) throws IOException {
        // 1 00000010 01000011 = 65536 + 2 * 256 + 67 = 66115
        // Creating a stream that repeats this number twice 
        // 10000001 00100001 1, 10000001 00100001 1
        // 10000001 00100001 11000000 10010000 11[000000] = 129, 33, 192, 144, 192
        byte[] data = { (byte) 129, 33, (byte) 192, (byte) 144, (byte) 192 };
        ByteArrayInputStream in = new ByteArrayInputStream(data);
        BitReader br = new BitReader(in);
        // Should print 66115, 66115, 0
        System.out.println(br.readBits17());
        System.out.println(br.readBits17());
        System.out.println(br.readBits(6));
    }
}

(Copyright: I hereby place this code in the public domain, for everyone to use as they see fit.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top