Git Product home page Git Product logo

bitbench's Introduction

BitBench

Visually dissect and analyze bit strings.

Using the BitBench

There is a hosted instance on http://triq.net/bitbench

Status

This is a quick 1-day proof-of-concept. Comments and Code very much welcome.

Development

  • Project setup yarn install

  • Compiles and hot-reloads for development yarn run dev

  • Compiles and minifies for production yarn run build

  • Run your tests yarn run test

  • Lints and fixes files yarn run lint

bitbench's People

Contributors

simonratner avatar zuckschwerdt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bitbench's Issues

Variable length data

I need an option to designate one or more bytes as a length, and then parse the following N bytes as the data.

For example:
30 00 05 aa bb cc dd ee 4f
30 00 01 ff d8
->
ID:30 LEN:0005 DATA:aabbccddeeff CRC:4f
ID:30 LEN:0001 DATA:ff CRC:d8

Rewrite the data access using a pointer instead of popping from array

I noticed the parser pops data from the array, effectively consuming it. This blocks #9 and in turn #8.

I suggest rewriting it to a bit-container with random-access and a walking 'current pointer'.

Here's my implementation in Java that you should be able to cannibalize.

public final class BitContainer {
	private final byte[] buffer;
	private final int    bitCapacity;

	private int pointer       = 0; // byte pointer
	private int remainingBits = 8; // Always in the range [1, 8]

	private BitContainer(byte[] buffer, int bitCapacity) {
		this.buffer = requireNonNull(buffer, "buffer");
		this.bitCapacity = bitCapacity;
	}

	public static BitContainer allocate(int bitCapacity) {
		requireAtLeast(1, bitCapacity, "bitCapacity");
		int    capacity = (bitCapacity + 7) / 8;
		byte[] buffer   = new byte[capacity];
		return new BitContainer(buffer, bitCapacity);
	}

	public int bitCapacity()    { return bitCapacity; }

	public int capacity()       { return (bitCapacity + 7) / 8; }

	public int remainingBits() { return bitCapacity - buffer.position() * 8 + remainingBits - 8; }

	public void setPointer(int bitPosition) {
		pointer = bitPosition / 8;
		remainingBits = 8 - (bitPosition & 7);
	}

	public byte[] getArray(int numBits) {
		requireThat((numBits & 7) == 0, "numBits not an integral number of bytes: " + numBits);
		if (numBits > remainingBits())
			throw new IndexOutOfBoundsException(numBits + " > " + remainingBits());

		byte[] array = new byte[numBits / 8];

		// Use more efficient method for byte-aligned bytes
		if (remainingBits == 8) {
			for (int i = 0; i < array.length; i++)
				array[i] = buffer[pointer++];
		} else {
			for (int i = 0; i < array.length; i++)
				array[i] = (byte)getBits(8);
		}

		return array;
	}

	public void putArray(byte[] array) {
		requireNonNull(array, "array");
		if (array.length * 8 > remainingBits())
			throw new IndexOutOfBoundsException(array.length * 8 + " > " + remainingBits());

		// Use more efficient method for byte-aligned bytes
		if (remainingBits == 8) {
			for (byte element : array)
				buffer[pointer++] = element;
		} else {
			for (byte element : array)
				putBits(8, element);
		}
	}

	public int getBits(int numBits) {
		requireRange(1, 32, numBits, "numBits");
		if (numBits > remainingBits())
			throw new IndexOutOfBoundsException(numBits + " > " + remainingBits());

		if (numBits < remainingBits) {
			// Get middle bits of this byte and don't advance byte pointer
			byte value  = buffer[pointer];
			int  result = extractBits(value, remainingBits - numBits, numBits);
			remainingBits -= numBits;
			return result;
		}

		int result;
		if (remainingBits != 8) {
			// Get all remaining bits of this byte and advance byte pointer
			byte value = buffer[pointer++];
			result = extractBits(value, 0, remainingBits);
			numBits -= remainingBits;
		} else {
			result = 0;
		}

		// Get middle bytes and advance byte pointer
		while (numBits >= 8) {
			result <<= 8;
			result |= buffer[pointer++] & 0xFF;
			numBits -= 8;
		}

		if (numBits > 0) {
			// Get remaining bits of this byte and don't advance byte pointer
			byte value = buffer[pointer];
			result <<= numBits;
			result |= extractBits(value, 8 - numBits, numBits);
		}

		remainingBits = 8 - numBits;

		return result;
	}

	public void putBits(int numBits, int bits) {
		requireRange(1, 32, numBits, "numBits");
		if (numBits > remainingBits())
			throw new IndexOutOfBoundsException(numBits + " > " + remainingBits());

		if (numBits < remainingBits) {
			// Put all bits in the middle of this byte and don't advance byte pointer
			byte value  = buffer[pointer];
			byte result = injectBits(bits, value, remainingBits - numBits, numBits);
			buffer[pointer] = result;
			remainingBits -= numBits;
			return;
		}

		if (remainingBits != 8) {
			// Fill remaining bits of this byte and advance byte pointer
			byte value    = buffer[pointer];
			int  highBits = extractBits(bits, numBits - remainingBits, remainingBits);
			byte result   = injectBits(highBits, value, 0, remainingBits);
			numBits -= remainingBits;
			buffer[pointer++] = result;
		}

		// Fill middle bytes and advance byte pointer
		while (numBits >= 8) {
			int value = extractBits(bits, numBits - 8, 8);
			buffer[pointer++] = (byte)value;
			numBits -= 8;
		}

		if (numBits > 0) {
			// Put remaining bits in this byte and don't advance byte pointer
			byte value   = buffer[pointer];
			int  lowBits = extractBits(bits, 0, numBits);
			byte result  = injectBits(lowBits, value, 8 - numBits, numBits);
			buffer[pointer] = result;
		}

		remainingBits = 8 - numBits;
	}

	private static int extractBits(byte value, int firstBit, int numBits) {
		int mask = (1 << numBits) - 1;
		return value >> firstBit & mask;
	}

	private static int extractBits(int value, int firstBit, int numBits) {
		int mask = (1 << numBits) - 1;
		return value >> firstBit & mask;
	}

	private static byte injectBits(int bits, byte value, int firstBit, int numBits) {
		int mask = ((1 << numBits) - 1) << firstBit;
		return (byte)((value & ~mask) | (bits << firstBit & mask));
	}
}

Don't care fields

Omit a field from output (e.g. padding or reserved bits).
Example: CH:3d ?5b ID:hh formats 60 c3 โ†’ CH:3 ID:c3.

Option to specify whether decimal integer fields are signed or unsigned

This is a great tool! I would like the option to specify whether a decimal value should be interpreted and displayed as a signed or an unsigned value. Currently it appears that a 16-bit decimal field is always interpreted as unsigned, whereas a 32-bit field is interpreted as signed. For example, this data:

258d2d2200000001000000000100000000ffffffffffff000000000000000000000000000000a7f38
hhhhhhhh hhhhhhhh hhhhhhhhhh hhhhhhhh 16d 32d 

displays:

258d2d22 00000001 0000000001 00000000 65535 00000000-1 00000000 00000000 0000000000 0000a7f3 08

Format bits as ASCII

It would be great to be able to format some data as ASCII characters. That's pretty much it =)

Allow reordering (addressing) fields

It would be useful (also for enhancement request #8) to be able to address a string of bits to allow reordering data and overlapping data.

For example:
00 11 22 33 44 55 66
with
A:16h B:16h C:{16@8}h D:{16@24}h
becomes:
A:0011 B:2233 C:1122 D:3344 ...

Continuation option 1. The 'current pointer' is always after the last bit ever read (as if by a max() function). Addressed access only pushes the pointer forward if it exceeds previously read data.

the above becomes:
A:0011 B:2233 C:1122 D:3344 A:5566 ...

Continuation option 2. The 'current pointer' should not be modified by an addressed field. Addressed field access just peeks into the data without modifying anything else.

the above becomes:
A:0011 B:2233 C:1122 D:3344 A:4455...

==Extras:==

<{16@24}h : The 16bit value starting bit 24 is interpreted little endian.
{16@-24}h : The 16bit value starting bit 24 before the current pointer.
{16@+24}h : The 16bit value starting bit 24 after the current pointer.

Byte swap values

Example: BE:>32d LE:<32d formats f04e0200 f04e0200 โ†’ BE:4031644160 LE:151280
For non-byte-multiples, maybe assume groups of 8 bits from the little end?

Highlight bits that have changed

Nice tool!

Would be nice if it could highlight bits that have/haven't changed between input lines. Or maybe add a row in the output that shows which bits change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.