Splitting a byte into bits - java

I have a byte array i.e from byte[0] to byte[2]. I want to first split byte[0] into 8 bits. Then bytes[1] and finally bytes[2]. By splitting I mean that if byte[0]=12345678 then i want to split as variable A=8,Variable B=7, variable C=6,Variable D=5,........ Variable H=0. How to split the byte and store the bits into variables? I want to do this in JAVA

well the bitwise operations seem to be almost what you're talking about.
a byte is composed of 8 bits, and so it goes in the rage of 0 to 255.
written in binary that's 00000000 to 11111111.
Bitwise operations are those that basically use masks to get out as much info as possible out of a byte.
Say for instance you have your 1101 0011 byte (space added for visibility only) = 211 (decimal). You can split that into 2 "variables" b1 and b2 of half a byte each. they'll thus cover the range of 0 to 15.
How you do this is by defining some masks. A mask to get your first half-a-byte-value would be 0000 1111.
You take your value of 11010011 apply the bitwise and (& ) operator to it.
So saying byte b = 211; byte mask1=15; OR byte b=0x11010011; byte mask1=0x00001111;
you then have your variable byte b1=b & mask1;
Thus applying that operation would result in b1=00000011 = 3;
With a mask byte mask2=0x11110000; applying the same operation on b, you'd get byte b2=mask2 & b = 0x11010000;
Now of course that leaves the number b2 possibly too large for you. All you have to do if you want to grab the value 0x1101 is to right shift it. Thus b2>>=4;
You can have your masks in any form, but it's usual to have them in decimal as the powers of 2 (so that you can take any bit out of your byte) or decide what range you want on your variables and make the mask "larger" like 0x00000011, or ox00001100. Those 2 masks would respectively get you 2 values from a byte, each value ranging from 0 to 3, values that you can fit 4 inside a byte.
for more info, chek out the relevant wiki.
Sorry, the values were a little off (since byte seems to go from -128 to 127, but the idea is the same.
Second edit (never used bitwise operations myself lol)... the "0x" notation is for hexadecimals. So you'll actually have to calculate for yourself what 01001111 actually means... pretty sucky :| but it's gonna do the trick.

boolean a = (theByte & 0x1) != 0;
boolean b = (theByte & 0x2) != 0;
boolean c = (theByte & 0x4) != 0;
boolean d = (theByte & 0x8) != 0;
boolean e = (theByte & 0x10) != 0;
boolean f = (theByte & 0x20) != 0;
boolean g = (theByte & 0x40) != 0;
boolean h = (theByte & 0x80) != 0;

Related

How do I create a method to generate all possible boolean functions?

I have used JAVA to create a linked list of 30 nodes. Each node is assigned a random Boolean value when instantiated.
I want each node assigned its own random boolean method/function/rule that takes three Boolean arguments and returns the result:
boolean assignedBolMethod(boolean a, boolean b, boolean c) {
boolean answer = conduct assigned ruled
return answer;
}
I understand there are 256 such rules to chose from (2^2^3); how could I generate all 256 possible rules without typing them out manually?
Let's say '0' when we mean false and '1' when we mean true, because that makes this a lot easier to read:
There are 8 different possible inputs (000, 001, 010, 011, 100, 101, 110, and 111), and for each input, there are 2 possible answers: 0 or 1.
Let's define a 'rule' as follows: We always list all the inputs in that exact order, and then we list the rule's answer to each input in terms of a 1 or a 0. Thus, 00001111 is the rule that says '000 = 0', '001 = 0, 010 = 0, 011 = 0, 100 = 1, ', etcetera - in other words, the rule is: return a;, if you were to put it in code.
It is then obvious that there are indeed 256 rules (2 ^ 8), and you can represent each rule as a single byte, as bytes consist of 8 bits. Every existing byte represents one rule. Thus 'a rule' and 'a byte' are completely interchangeable, thus, this boils down to: How do I generate an arbitrary byte.
And that's easy:
Random r = new Random(); // do this once someplace
byte rule = r.nextByte();
Alternatively if you want an ordered list of every possible rule:
byte[] rules = new byte[256];
for (int i = 0; i < rules.length; i++) rules[i] = (byte) i;
But this array is mostly meaningless; it effectively maps '100' to '100' - not very useful. There is no actual need to have a 'list' of all possible rules: Java already ships with it: byte - that is a data type that exactly matches. Thus, if you have some code and you want 'rule 100' to be applied, all you need to write is byte rule = 100; - no need for a list.
Given a byte that represents a rule, plus those 3 inputs, how do you determine the answer the rule indicates is correct?
Well, first you need to collapse those 3 booleans you have into which one of the 8 bits in your byte represents the answer.
int bitPos = (a ? 1 : 0) + (b ? 2 : 0) + (c ? 4 : 0);
This gives you the position of the bit (a number between 0 and 7) that determines the answer.
Then, given a bit position and a byte:
boolean answer = ((rule >> bitpos) & 1) != 0;
Breaking that down:
a >> b will take the bitstring of a (let's say it's rule 00110111), and shift it to the right by b spots. So if we want the bit at bitpos=2 (so, the third bit), 0b00110111 >> 2 is 0b00001101. This means the bit we are interested in is now at the very end.
a & b will take the bitstring of a, and the bitstring of b, and checks for all positions where both a and b have a 1. Then, it returns a new number represented by setting each bit to 1 where both a and b have a one. Therefore, a & 1 has the effect of zeroing out all bits, except the lowest bit (1 = 00000001 - all bits unset except the lowest bit). It gets rid of all bits, except the bit we care about.
!= 0 then just checks if that bit was set or not.

What is the purpose of low and high nibble when converting a string to a HexString

Recently I have been going through some examples of MD5 to start getting an understanding of security and MD5 has been fairly simple to understand for the most part and a good starting point even though it is no longer secure. Despite this I have a question regarding high and lo nibbles when it comes to converting a string to a hex string.
So I know high and low nibbles are equal to half a byte or also can be hex digits that represent a single hexadecimal digit. What I am not understanding though is exactly how they work and the purpose that they serve. I have been searching on google and I can't find much of an answer that will help explain what they do in the context that they are in. Here is the context of the conversion:
private static String toHexString( byte[] byteArray )
{
final String HEX_CHARS = "0123456789ABCDEF";
byte[] result = new byte[byteArray.length << 1];
int len = byteArray.length;
for( int i = 0 ; i < len ; i++ )
{
byte b = byteArray[i]
int lo4 = b & 0x0F;
int hi4 = ( b & 0xF0 ) >> 4;
result[i * 2] = (byte)HEX_CHARS.charAt( hi4 );
result[i * 2 + 1] = (byte)HEX_CHARS.charAt( lo4 );
}
return new String( result );
}
I don't exactly understand what is going on in the for statement. I would appreciate any help understanding this and if there is some link to some places that I can learn more about this please also leave it.
I understand the base definition of nibble but not the operations and what the assignment to the number 4 is doing either.
If I need to post the full example code I will just ask as I am unsure if it is needed.
This code simply converts a byte array to hexadecimal representation. Within the for-loop, each byte is converted into two characters. I think it's easier to understand it on an example.
Assume one of the bytes in your array is, say, 218 (unsigned). That's 1101 1010 in binary.
lo4 gets the lowest 4 bits by AND-ing the byte with the bitmask 00001111:
int lo4 = b & 0x0F;
This results in 1010, 10 in decimal.
hi4 gets the highest 4 bits by AND-ing with the bitmask 1111 0000 and shifting 4 bits to the right:
int hi4 = ( b & 0xF0 ) >> 4;
This results in 1101, 13 in decimal.
Now to get the hexadecimal representation of this byte you only need to convert 10 and 13 to their hexadecimal representations and concatenate. For this you simply look up the character in the prepared HEX_CHARS string at the specific index. 10 -> A, 13 -> D, resulting in 218 -> DA.
It's just bit operations. The & character takes the literal bit value of each and does a logical and on them.
int lo4 = b & 0x0F;
for instance if b = 24 then it will evaluate to this
00011000
+00001111
=00001000
The second such line does the same on the first four bits.
00011000
+11110000
=00010000
the '>>' shifts all of the bits a certain number in that direction so
00010000 >> 4 = 00000001.
This is done so that you can derive the hex value from the number. Since each character in hex can represent 4 bits by splitting the number into pieces of 4 bits we can convert it.
in the case of b = 24 we no have lo4 = 1000 or 8 and hi4 = 0001 or 1. The last part of the loop assigns the character value for each.
Hex_chars[hi4] = '1' and Hex_chars[lo4] = '8' which gives you "18" for that part of the string which is 24 in hex.

Undoing bitwise operations

I have a Java function written by another programmer, which uses bitwise manipulation. I need a function that will undo the process (if possible). Perhaps some of you are more savvy than I with these operators. Here's what needs to be undone:
public void someFunc(int[] msg, int[] newMsg) {
int i = SOME_LENGTH_CONSTANT;
for (int j = 0; j < newMsg.length; j++) {
// msg[i] Shift left by 8 bits bitwise or with next msg[i+1]
// then bitwise not (~) and bitwise and with $FFF
newMsg[j] = (~(((msg[i] & 0x0f) << 8) | (msg[i + 1]))) & 0xfff;
i += 2;
}
}
I just wanted to try to do it, here is the results of my attempt.
In the beginning I split the expression into single operations:
int t1 = msg[i] & 0x0f;
Here is we lose all except for the last 4 bits.
int t2 = t1 << 8;
Clear low 8 bits by shifting t1.
int t3 = t2 | msg[i + 1];
Here we should understand if m[i + 1] is large than 255 (particularly m[i + 1] & 0xf00 > 0), we are not able to restore the low 4 bits of m[i] because they are irreversibly overwritten.
int t4 = ~t3;
Just a negation.
newMsg[j] = t4 & 0xfff;
Take low 12 bits.
Just did these steps in reverse order:
public static void someFuncRev(int[] msg, int[] newMsg) {
for (int i = 0; i < msg.length; ++i) {
newMsg[2 * i] = (~msg[i] >> 8) & 0xf; // take 11-8 bits
newMsg[2 * i + 1] = ~msg[i] & 0xff; // take 7-0 bits
}
}
I assumed SOME_LENGTH_CONSTANT == 0. It is easy to adjust the constant.
So, when the values inside msg are <=15, the function above recovers the initial sequence.
In case when the values are >15 and <=255, for msg[i] we can restore only 4 bits, msg[i + 1] are restored completely.
If the values are >255, we can't restore msg[i] because it was correpted by bits of msg[i + 1] (look above at the point no. 3); can restore 8 bits of msg[i + 1].
I hope this helps you.
My version, behold:
public void undoFunc(int[] newMsg, int[] original) {
int i = SOME_LENGTH_CONSTANT; // starting point
for (int j = 0; j < newMsg.length; j++) { // Iterate over newMsg
original[i] = ~((newMsg[j]&0xff00)>>8)&0x000f; // &0x000f to get rid of "mistakes" when NOT-ing
original[i+1] = (~(newMsg[j]&0x00ff)) & 0xff;
// i = initial value + 2 * j
i+=2;
}
}
What does your code do?
The input is an integer array. Every two values are used to create one value in the 'output' (newMsg) array.
First, it removes the left four bits of the first value in the input.
Then it "scrolls" that value 8 places to the left and puts zeroes in the empty spots.
It places the second value, msg[i+1], in the zeroes in the four rightmost bits.
It negates the value, all ones become zeroes and all zeroes become ones.
When 4) was done, the 4 leftmost bits (cleared in step 1)) become ones, so it undoes this with a &0x0FFF.
Example iteration:
msg[i] == 1010'1011
msg[i+1] == 0010'0100
1) 1010'1011 -> 0000'1011
2) 0000'1011 -> 0000'1011'0000'0000
3) 0000'1011'0000'0000 -> 0000'1011'0010'0100
4) 0000'1011'0010'0100 -> 1111'0100'1101'1011
5) 1111'0100'1101'1011 -> 0000'0100'1101'1011
newMsg[j] == 0000'0100'1101'1011 == 0x04DB (I think, from memory)
What my code does:
Getting the value of (what used to be) msg[i+1] is easy, it's the opposite/NOT of the rightmost 8 bits. Because negating it turns all leading zeroes into ones, I'll AND it with 0xff.
Getting the value of (what used to be) msg[i] was more difficult. First scrolled the leftmost 8 bits to the right. Then I negate the value. But the four unused/lost bits are now ones, and I expect that the OP wants these to be zeroes, so I &0x000f it.
NOTE: I used hexes with leading zeroes to make it more clear. These are not necessary.
NOTE: I divided the binary numbers into four bits for readability. So 0000'0100'1101'1011 is actually (0b)0000010011011011.
The values of msg[i+1] are recovered, but the leftmost four bits of msg[i] are lost.
Fwew.
Original Post:
In your code, you use &. What & does, is turn all 'agreeing bits' (when a bit from byte a and the equally significant bit from byte b are both 1) into 1s and the rest into 0s. This means that all bits that don't agree are, as #Mike Harris said, gone and destroyed.
Example & (and operation):
1010 & 0110 =
1 & 0 => 0
0 & 1 => 0
1 & 1 => 1
0 & 0 => 0
= 0010
As you see, only the second and third most significant bits (or zero-inclusive first and second least significant bit) of byte a are kept (bit #4/#0 is 'luck'), because they are 1s in byte b.
You can reverse all bits that are 1s in byte b in your code (one of which is fff, or 1111 1111 1111 in binary, though remember all bits more significant than the first one are removed, because 1111 1111 1111 == 000000000...00111111111111). But this won't reverse it, and only works depending on what the purpose of reversing it is.
More about the AND Bitwise operation on Wikipedia.

How to extract and display each of the four bytes of an integer individually as 8-bit values

edit: This question is not a duplicate. The whole point is to solve the question using masks and bit shifts.
I have a terrible programming teacher that introduces concepts without explaining them or providing material to understand them, and he's to arrogant and confrontational too seek help from.
So naturally, I'm stuck on yet another question without any guidance.
Given an integer variable x, write Java code to extract and display each of the four bytes of that integer individually as 8-bit values.
I'm supposed to use masking and bit shift operations to answer this question. I understand that masking means turning bits "on or off" and I understand that an integer has 32 bits or 4 bytes. But that information doesn't help me answer the question. I'm not necessarily asking for the entire solution, but any help would be appreciated.
Using masks and shifting to extract bytes from an integer variable i,
The bytes from most significant (highest) to least are:
byte b3 = (byte)((i>>24));
byte b2 = (byte)((i>>16)&255);
byte b1 = (byte)((i>>8)&255);
byte b0 = (byte)((i)&255);
out.println("The bytes are " + b3 + ", " + b2 + ", " + b1 + ", " + b0);
You could use a ByteBuffer
int myInt = 123;
byte[] bytes = ByteBuffer.allocate(4).putInt(myInt).array();
Then you can do whatever you want with it. If you want all bits you could do something like this:
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
if(bytes[i] & (1 << j))
{
System.out.print("1");
}
else
{
System.out.print("0");
}
}
System.out.print(" ");
}
I have not tested this code because I do not have Java on this PC, but if it does not work let me know. However this sould give you a ruff idea of what has to be done.
Firstly you have to understand bitwise operators and operations. ( https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html )
Boolean logic states that x & 1 = x and x & 0 = 0.
Knowing this we can create a mask for, lets say the least significant 4 bits of an 8 bit number: 11001101 & 00001111 = 1101 (205 & 0x0f = 13).
(we ignore the first 4 zeros and we got our 4 bits)
What if we need the most significant bits?
we apply the same idea, but now the mask will change, according to the bits we need: 11001101 & 11110000 = 11000000 (205 & 0xf0 = 192)
whoops... we got 4 zeros.
How can you get rid of that? Shifting to the right with 4 positions.
so 11000000 >> 4 = 1100 (most significant 4 bits)
I hope this example will help you to get a better understanding of bitwise operations.
One simple solution could be
bit0 = (x & 0xff000000) >> 24;
bit1 = (x & 0x00ff0000) >> 16;
bit2 = (x & 0x0000ff00) >> 8;
bit3 = (x & 0x000000ff);
(bit0 is MSB).
Masking isn't quite turning bits "on" or "off". It is a way to extract only the bits you want from the variable you are using. Lets say that you have the binary number 10011011 and you want the value of the rightmost 4 bits. To do this, you construct another binary number of the same length where there are 0's in the places that you don't want and 1's in the places that you do. Therefore, our binary number is 00001111. You then bitwise AND them together:
1 & 0 = 0
0 & 0 = 0
0 & 0 = 0
1 & 0 = 0
1 & 1 = 1
0 & 1 = 0
1 & 1 = 1
1 & 1 = 1
In java, using hex instead of binary since java doesn't have binary literals, this looks like
int result = 0x9B & 0x0F;
//result is 0xB (or 11 in decimal)
Bit shifting is just what it sounds like. If you have 10011111 and shift it right 2 bits you get 00100111. In java a bit shift of 2 looks like
int result = 0x9B >> 2;
For your program the idea is this:
Mask the rightmost byte of your integer
Shift integer right 8 bits
Repeat three more times

How are integers cast to bytes in Java?

I know Java doesn't allow unsigned types, so I was wondering how it casts an integer to a byte. Say I have an integer a with a value of 255 and I cast the integer to a byte. Is the value represented in the byte 11111111? In other words, is the value treated more as a signed 8 bit integer, or does it just directly copy the last 8 bits of the integer?
This is called a narrowing primitive conversion. According to the spec:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
So it's the second option you listed (directly copying the last 8 bits).
I am unsure from your question whether or not you are aware of how signed integral values are represented, so just to be safe I'll point out that the byte value 1111 1111 is equal to -1 in the two's complement system (which Java uses).
int i = 255;
byte b = (byte)i;
So the value of be in hex is 0xFF but the decimal value will be -1.
int i = 0xff00;
byte b = (byte)i;
The value of b now is 0x00. This shows that java takes the last byte of the integer. ie. the last 8 bits but this is signed.
or does it just directly copy the last
8 bits of the integer
yes, this is the way this casting works
The following fragment casts an int to a byte. If the integer’s value is larger than the range of a byte, it will be reduced modulo (the remainder of an integer division by the) byte’s range.
int a;
byte b;
// …
b = (byte) a;
Just a thought on what is said: Always mask your integer when converting to bytes with 0xFF (for ints). (Assuming myInt was assigned values from 0 to 255).
e.g.
char myByte = (char)(myInt & 0xFF);
why? if myInt is bigger than 255, just typecasting to byte returns a negative value (2's complement) which you don't want.
Byte is 8 bit. 8 bit can represent 256 numbers.(2 raise to 8=256)
Now first bit is used for sign. [if positive then first bit=0, if negative first bit= 1]
let's say you want to convert integer 1099 to byte. just devide 1099 by 256. remainder is your byte representation of int
examples
1099/256 => remainder= 75
-1099/256 =>remainder=-75
2049/256 => remainder= 1
reason why? look at this image http://i.stack.imgur.com/FYwqr.png
According to my understanding, you meant
Integer i=new Integer(2);
byte b=i; //will not work
final int i=2;
byte b=i; //fine
At last
Byte b=new Byte(2);
int a=b; //fine
for (int i=0; i <= 255; i++) {
byte b = (byte) i; // cast int values 0 to 255 to corresponding byte values
int neg = b; // neg will take on values 0..127, -128, -127, ..., -1
int pos = (int) (b & 0xFF); // pos will take on values 0..255
}
The conversion of a byte that contains a value bigger than 127 (i.e,. values 0x80 through 0xFF) to an int results in sign extension of the high-order bit of the byte value (i.e., bit 0x80). To remove the 'extra' one bits, use x & 0xFF; this forces bits higher than 0x80 (i.e., bits 0x100, 0x200, 0x400, ...) to zero but leaves the lower 8 bits as is.
You can also write these; they are all equivalent:
int pos = ((int) b) & 0xFF; // convert b to int first, then strip high bits
int pos = b & 0xFF; // done as int arithmetic -- the cast is not needed
Java automatically 'promotes' integer types whose size (in # of bits) is smaller than int to an int value when doing arithmetic. This is done to provide a more deterministic result (than say C, which is less constrained in its specification).
You may want to have a look at this question on casting a 'short'.

Categories

Resources