java - Get Bit values from Byte Array -
i have byte array need read specific bits , convert int (see byte array structure below). though bits information want read in 3 bytes, tried reading 4 bytes (6-9) integer , read bits integer value bits or bitsvalue method somehow not able see right values bit manipulation. , expertise in bits pretty sure doing wrong. can please suggest doing correctly , why not working. in advance!!
byte array in little endian format.
0th byte - value 1st byte - value 2nd - 5th byte - value 6th - 9th byte - first 18 bits represent value - next 5 bits represent value - next 1 bit represent value - last 8 bits represent value
public class test { public static void main(string... dataprovider) { string s = "46 00 ef 30 e9 08 cc a5 03 43"; byte[] bytes = new byte[s.length()]; bytes = hexstringtobytearray(s); int bytepointer = 0; int msgtype = getintfromsinglebyte(bytes[bytepointer]); // 0th byte int version = getintfromsinglebyte(bytes[++bytepointer]); // 1st byte int tickinms = getintvalue(bytes, ++bytepointer); // 2nd-5th bytes bytepointer = bytepointer + 4; int headr = getintvalue(bytes, bytepointer); // 6th-9th bytes int utctime = bits(headr, 0, 18); // 6th-9th bytes - 18 bits int reserved = bits(headr, 18, 5); // 6th-9th bytes- 5 bits int reportorevent = bits(headr, 23, 1); // 6th-9th bytes - 1 bits int reportid = bitsvalue(headr, 24, 32); // 6th-9th- 8 bits } public static int getintfromsinglebyte(byte data) { return (data & 0xff); } public static int getintvalue(byte[] bytes, int startposition) { byte[] dest = new byte[4]; system.arraycopy(bytes, startposition, dest, 0, dest.length); return toint(dest); } // took stack overflow static int bits(int n, int offset, int length) { // shift bits rightward, desired chunk @ right end n = n >> (31 - offset - length); // prepare mask rightmost `length` bits 1's int mask = ~(-1 << length); // 0 out bits right chunk return n & mask; } public static int bitsvalue(int intnum, int startbitpos, int endbitpos) { // parameters checking ignored int tempvalue = intnum << endbitpos; return tempvalue >> (startbitpos + endbitpos); } public static byte[] hexstringtobytearray(final string s) { string[] splits = s.split(" "); final byte[] data = new byte[splits.length]; (int = 0; < splits.length; i++) { char first = splits[i].length() < 2 ? '0' : splits[i].charat(0); char second = splits[i].length() < 2 ? splits[i].charat(0) : splits[i].charat(1); data[i] = (byte) ((character.digit(first, 16) << 4) + character.digit(second, 16)); } return data; } public static int toint(byte[] data) { if (data == null || data.length != 4) return 0x0; return (int) ((0xff & data[0]) << 24 | (0xff & data[1]) << 16 | (0xff & data[2]) << 8 | (0xff & data[3]) << 0); } }
wrapping input data in bytebuffer
simplify parsing , allow adjust endianness necessary.
your bits
method wrong. constant 31 should 32. also, method uses msb 0 bit numbering, odd little-endian data. should confirm input documented using bit numbering scheme.
your bitsvalue
method wrong too. may use bits
after fixing it.
this code simpler , extracts bit fields correctly:
public static void main(string... args) { string s = "46 0 79 37 a8 3 9f 37 1 43 eb 7a f 3 3 fe c4 1 c5 4 c5 5e"; byte[] input = hexstringtobytearray(s); // wrap input in bytebuffer parsing. adjust endianness if necessary. bytebuffer buffer = bytebuffer.wrap(input).order(byteorder.big_endian); int msgtype = buffer.get() & 0xff; int version = buffer.get() & 0xff; int tickinms = buffer.getint(); int header = buffer.getint(); int utctime = bits(header, 0, 18); // 6th-9th bytes - 18 bits int reserved = bits(header, 18, 5); // 6th-9th bytes - 5 bits int reportorevent = bits(header, 23, 1); // 6th-9th bytes - 1 bit int reportid = bits(header, 24, 8); // 6th-9th bytes - 8 bits system.out.printf("utc: %d, report? %d, id: %d\n", utctime, reportorevent, reportid); } /** * extract bit field int. bit numbering msb 0. */ public static int bits(int n, int offset, int length) { return n >> (32 - offset - length) & ~(-1 << length); }
Comments
Post a Comment