I have never used bytes in Java before, so I am unfamiliar with the sytnax for manipulating bytes and bits. I searched how to do this task, but I can't find a simple solution.
I have a byte b. b has eight bits. I would like to flip the ith bit of b to its negation (0 -> 1, 1 -> 0). How do I do this?
I think this will work:
byte b = 0; // initial val ...0000000
final int theNumberofTheBitToFlip = 2; // bit to flip
b = (byte) (b ^ (1 << theNumberofTheBitToFlip));
System.out.println(b); // result ...0000100 = 8
b = (byte) (b ^ (1 << theNumberofTheBitToFlip));
System.out.println(b);// result ...0000000 = 8
Try this
int i=3;
b = (byte) (b ^ (1 << i));
Related
Given an array filled with 4 bytes inside (R,G,B,A), I'm trying to translate this array full of 4 8bits numbers into its translation in 32bits. To be more clear, if I get an array such as:
byte[] tab = {1,2,3,4};
with translated in binary in 8bit :
1 = 0b00000001
2 = 0b00000010
3 = 0b00000011
4 = 0b00000100
Then, my method should return a byte array such as :
newTab = {00000001_00000010_00000011_00000100};
For some reason, I'm trying to do this without using a String to concatenate the bytes.
I've already tried something with binary operators such as <<, >> or |, but without success...
So far, my code looks like this :
byte[] tab = {1,2,3,4};
int tmp,tabToInt = 0;
for (int x = 0 ; x < tab.length ; ++x){
tmp = tmp << (tab.length - 1 - x)*8;
byteToInt = byteToInt | tmp;
}
return tabToInt;
But it didn't seem to work, even less with negatives bytes... (like -1 = 0b11111111)
Thanks in advance for your answers!
You can use ByteBuffer like this.
byte[] tab = {1, 2, 3, 4};
int tabToInt = ByteBuffer.wrap(tab).getInt();
System.out.println("decimal = " + tabToInt);
System.out.println("binary = " + Integer.toBinaryString(tabToInt));
System.out.println("hexadecimal =" + Integer.toHexString(tabToInt));
output
decimal = 16909060
binary = 1000000100000001100000100
hexadecimal =1020304
ByteBuffer can do it, but only if you get passed at least 4 bytes.
The problem with your code is two-fold:
I think you typoed somewhere, your code doesn't even compile. I think you meant tmp = tab[x] << (tab.length - 1 - x)*8;. Your snippet never does anything with tab other than ask for its length.
Negative numbers extend, and java will convert any byte or short to an int the moment you do any math to it. So, 0b1111 1111, if you try to do e.g. << 8 on that, java first turns that -1 byte into a -1 int (so that's now 32 1 bits), and then dutifully left shifts it by 8, so now that's 24 1 bits, followed by 8 0 bits. You then bitwise OR that into your target, and thus now the target is mostly 1 bits. To convert a byte to an int without "sign extension", (b & 0xFF does it:
byte b = (byte) 0b1111_1111;
assert b == -1; // yup, it is
int c = b; // legal
assert c == -1; // yeah, still is. uhoh. That's...
int d = 0b11111111_11111111_11111111_11111111;
assert c == d; // yeah. We don't want that.
int e = (b & 0xFF);
assert e = 255;
int f = 0b0000000_0000000_0000000_11111111;
assert e == f; // yes!
I am trying to convert an Integer to a byte array (array of 4 bytes) and then I will extract the last 4 bits of each byte, then I will create a short from those last 4 digits of each bytes.
I have the following code but it always prints zero.
private static short extractShort(byte[] byteArray) {
short s = 1;
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
for(int i = 0; i < byteArray.length; i++) {
byte lastFourBytes = extractLast4Bits(byteArray[i]);
// Uses a bit mask to extract the bits we are interested in
byteBuffer.put(lastFourBytes);
}
return ByteBuffer.wrap(byteBuffer.array()).getShort();
}
private static byte extractLast4Bits(byte byteParam) {
return (byte) ( byteParam & 0b00001111);
}
private static byte[] intToByteArray(int i) {
return new byte[] {
(byte)((i >> 24) & 0xff),
(byte)((i >> 16) & 0xff),
(byte)((i >> 8) & 0xff),
(byte)((i >> 0) & 0xff),
};
}
}
Any help will be sincerely appreciated
Once you get the byte array, try this..
short val = 0;
for (byte b : bytes) {
val <<= 4;
val |= (b&0xf)
}
If you want to do it starting from an int, you can do it like this.
int v = 0b1110_1010_1111_1001_1010_1000_1010_0111;
short verify = (short) 0b1010_1001_1000_0111;
// initialize a short value
short val = 0;
// increment from 24 to 0 by 8's the loop will
// repeat 4 times.
for (int i = 24; i >= 0; i -= 8) {
// start by shifting the result left 4 bits
// first time thru this does nothing.
val <<= 4;
// Shift the integer right by i bits (first time is
// 24, next time is 16, etc
// then mask off the lower order 4 bits of the right
// most byte and OR it to the result(val).
// then when the loop continues, val will be
// shifted left 4 bits to allow for the next "nibble"
val |= ((v >> i) & 0xf);
}
System.out.println(val);
System.out.println(verify);
For more information on bitwise operators, check out this Wikipedia link.
I have this line below where byte[] shaBytes with value from a SHA1. The first four is added to result to a number which is used in a while loop. I'm trying to port an objC code to java while the line below results to a negative value such as -2063597568 after several iterations.
long tVar = (shaBytes[0] << 24) + (shaBytes[1] << 16) + (shaBytes[2] << 8) + (shaBytes[3] << 3);
So basically, the while loop loops when
tVar > 0xFFFFFFFFL >> 11
In objC shaBytes is an unsigned char which is used as parameter in a CC_SHA1. In objC the code would loop up 700+ iterations while my port only 3 because tVar becomes negative.
Java doesn't have unsigned bytes. All Java integer types are signed. This means that the left shift of a negative byte will be negative:
byte b = -30;
long x = b << 24;
System.out.printf("x = %d\n", x);
// prints -503316480
On other hand if you convert byte to long everything'll turn out okay:
byte b = -30;
long x = (b & 0xffL) << 24;
System.out.printf("x = %d\n", x);
// prints 3791650816
To convert byte to "unsigned" (remember, there is no unsigned stuff in Java) long value use:
long tVar = ((shaBytes[0] & 0xffL) << 24) + ((shaBytes[1] & 0xffL) << 16) + etc
This'll work because Java long is 64-bit and can handle 24 left shift of 8-bit value without signed/unsigned problems.
Say you are having a byte of pattern:
byte b = 0x%1;
How to tell when a byte does have certain values on the "2nd position" - in place of % ?
In this example 1, no matter what the 1st position holds.
Use a mask bits to get the last 8 bits:
int last8bits = b & 0xF;
Edit: You should read up on bitwise operations.
Full example:
public static void main(String[] args) {
byte b = (byte) 0xA1;
int last8bits = b & 0xF;
if (last8bits == 0x01)
System.out.println("\"matches\"");
}
if ((0x0F & b) == 0x01) {
// pattern matched
Given
private int width = 400;
private byte [] data = new byte [2];
I want to split the integer "width" into two bytes and load data[0] with the high byte and data[1] with the low byte.
That is binary value of 400 = 1 1001 0000
so data[0] should contain 0000 0001
and data[1] should contain 1001 0000
Using simple bitwise operations:
data[0] = (byte) (width & 0xFF);
data[1] = (byte) ((width >> 8) & 0xFF);
How it works:
& 0xFF masks all but the lowest eight bits.
>> 8 discards the lowest 8 bits by moving all bits 8 places to the right.
The cast to byte is necessary because these bitwise operations work on an int and return an int, which is a bigger data type than byte. The case is safe, since all non-zero bits will fit in the byte. For more information, see Conversions and Promotions.
Edit: Taylor L correctly remarks that though >> works in this case, it may yield incorrect results if you generalize this code to four bytes (since in Java an int is 32 bits). In that case, it's better to use >>> instead of >>. For more information, see the Java tutorial on Bitwise and Bit Shift Operators.
For converting two bytes the cleanest solution is
data[0] = (byte) width;
data[1] = (byte) (width >>> 8);
For converting an integer to four bytes the code would be
data[0] = (byte) width;
data[1] = (byte) (width >>> 8);
data[2] = (byte) (width >>> 16);
data[3] = (byte) (width >>> 24);
It doesn't matter whether >> or >>> is used for shifting, any one bits created by sign extension will not end up in the resulting bytes.
See also this answer.
This should do what you want for a 4 byte int. Note, it stores the low byte at offset 0. I'll leave it as an exercise to the reader to order them as needed.
public static byte[] intToBytes(int x) {
byte[] bytes = new byte[4];
for (int i = 0; x != 0; i++, x >>>= 8) {
bytes[i] = (byte) (x & 0xFF);
}
return bytes;
}
Integer is 32 bits (=4 bytes) in java, you know?
width & 0xff will give you the first byte,
width & 0xff00 >> 8 will give you the second, etc.
To get the high byte, shift right by 8 bits then mask off the top bytes. Similarly, to get the low byte just mask off the top bytes.
data[0] = (width >> 8) & 0xff;
data[1] = width & 0xff;
int width = 400;
byte [] data = new byte [2];
data[0] = (byte) ((width & 0xFF00) >> 8);
data[1] = (byte) (width & 0xFF);
for(int b = 0; b < 2; b++) {
System.out.println("printing byte " + b);
for(int i = 7; i >= 0; i--) {
System.out.println(data[b] & 1);
data[b] = (byte) (data[b] >> 1);
}
}
I suggest you have a look at the source for HeapByteBuffer. It has the conversion code for all primitive data types. (In fact you could just use a ByteBuffer ;)