public class BitString implements Cloneable { private byte[] string; private int length; /** * Creates a new BitString filled with the length bits from data. * * @param data * input data * @param length * the length of the new BitString */ public BitString(byte[] data, int length) { if (length < 1) throw new IllegalArgumentException("length must be bigger than 0"); if (data == null) throw new IllegalArgumentException("data may not be null"); if ((length - 1) / 8 + 1 > data.length) throw new IllegalArgumentException( "data contains not enough elements for length: " + length); string = new byte[(length - 1) / 8 + 1]; for (int i = 0; i < string.length - 1; i++) string[i] = data[i]; this.length = length; // set unused bits in last byte to zero! if (length % 8 == 0) { // no unused bits string[string.length - 1] = data[string.length - 1]; } else { // apply bitmask byte mask = (byte) (255 << (8 - length % 8)); string[string.length - 1] = (byte) (data[string.length - 1] & mask); } } /** * Creates an empty BitString */ public BitString() { this.length = 0; } /** * Append a bit to the BitString * * @param the * bit to append to string * @return returns the complete BitString (this) */ public BitString append(boolean bit) { if (this.length % 8 == 0) { this.grow(1); } if (bit) { // set bit string[length / 8] = (byte) (string[length / 8] | (1 << (7 - length % 8))); } length++; return this; } /** * Clones the BitString * * @see java.lang.Object#clone() */ public BitString clone() { return string == null ? new BitString() : new BitString(string.clone(), length); } /** * Returns the BitString as byte array * * @return byte array or null if no bits are in BitString */ public byte[] getByteArray() { return (this.string == null) ? null : this.string.clone(); } /** * Returns the BitString as an boolean array * * @return boolean array or null if no bits are in BitString */ public boolean[] getBitArray() { // return "empty array" if (this.length == 0) return null; // build array boolean[] result = new boolean[this.length]; int bitShift = 7; int arrayPos = 0; int resultPos = 0; for (int i = 0; i < this.length; i++) { result[resultPos++] = (string[arrayPos] & 1 << bitShift) != 0; if (--bitShift < 0) { bitShift = 7; arrayPos++; } } return result; } /** * Returns the cirrent length of the BitString (in bits) * * @return the length of the BitString in bits */ public int getLength() { return this.length; } /** * Allocates more space for bits * * @param size */ private void grow(int size) { if (this.string == null) { this.string = new byte[size]; } else { // create new array byte[] newString = new byte[this.string.length + size]; // copy old content for (int i = 0; i < this.string.length; i++) newString[i] = this.string[i]; // replace array this.string = newString; } } /** * Returns a '0', '1' string * * @see java.lang.Object#toString() */ public String toString() { StringBuffer buffer = new StringBuffer(); int bitShift = 7; int arrayPos = 0; for (int i = 0; i < this.length; i++) { buffer.append((string[arrayPos] & 1 << bitShift) != 0 ? "1" : "0"); if (--bitShift < 0) { bitShift = 7; arrayPos++; } } return buffer.toString(); }}