Push 4 bits into an int in java - java

For an implementation of a SPN crypografic feature (studies related) I'm trying to push 4bits into an int.
I can pinpoint the mistake, but I don't know how to fix it (might stared too long at it for now).
private int applySBox(int a, boolean inverse, boolean verbose) {
// split int (16 bit) into parts of 4 bit keeping the right order
int[] parts = new int[4];
for(int i = 0; i < 4; i++) {
parts[4 - i - 1] = a & 0b1111;
a = a >> 4;
}
// Apply the SBox to each 4 bit
// E.g. 1101 traverse (enc) = 1001, inverse (dec) = 0010
for(int i = 0; i < 4; i++) {
if(inverse) {
parts[i] = sbox.inverse(parts[i]);
} else {
parts[i] = sbox.traverse(parts[i]);
}
}
int result = 0;
// put back together
for(int i = 0; i < 4; i++) {
result = parts[i] & 0b1111;
// TODO: Reassigning does not help here, needs shift and &
result = result << 4;
}
return result;
}
Before the SBox I might get a value of 1100111011001111 as cipher text.
In the split portion I get something like this:
Fragment[0]: 0001100011110000
Round Value: 0001100011110000
Current key: 1101011000111111
New r Value: 1100111011001111
---
Before SBox: 1100_1110_1100_1111
Part[0] before SBox: 1100
Part[1] before SBox: 1110
Part[2] before SBox: 1100
Part[3] before SBox: 1111
Part[0] after SBox: 1011
Part[1] after SBox: 0000
Part[2] after SBox: 1011
Part[3] after SBox: 0101
I know this is correct based on the defintion of the SBox I have to use.
This would mean, that in order to get the result I have to push parts 0 to 3 pack into one int 1011_0000_1011_0101 and it would be the correct result.
I can clearly see that it won't work because I always overwrite the result with result = parts[i] & 0b1111; I just can't seem to find a fix.
How can I push an int[] array each int with 4 bits worth of data in the order from 0 to 3 into the int result containing 16 bit of data?

If you shift the bits to the left then the rightmost bits fill up with zeros. So then you need to XOR or OR the results into place.
Try and replace
result = parts[i] & 0b1111;
with
result ^= parts[i] & 0b1111;
or
result |= parts[i] & 0b1111;
otherwise you are simply reassigning the value and delete the previous 4 bit blocks.

Do you mean:
result = (result << 4) | parts[i];
or, same thing written differently:
result |= parts[i] << (4 * (4-i));
If so then, yes, you stared too long at the screen and "got square eyes" as they say!
Update: Since OP implies it's OK to lock-in four parts. Here's an untested one-liner for the traverse variant:
return sbox.traverse(a & 0b1111)
| sbox.traverse(a >> 4 & 0b1111) << 4
| sbox.traverse(a >> 8 & 0b1111) << 8
| sbox.traverse(a >> 12 & 0b1111) << 12

Related

Bit circular shift

I am currently learning on bit-wise operations, and i am tasked to do a left rotate of 4-bit integer.
My code for a 4bit left rotate is
private static int BITS_IN_INTEGER = 4;
private static int leftRotate(int x, int n) {
return (x << n) | (x >> (BITS_IN_INTEGER - n));
}
I want to make a 4-bit circular shift to maintain as a 4-bit after rotating but can't seem to understand how it works.
Example: 10 (1010) after left rotate by 1 bit will give me 5 (0101) but it gives me a value of 21 which is more than my 4-bit.
Any help to make me understand this problem will be much appreciated!
If I understood you correctly, you want to
emulate integers with BITS_IN_INTEGER many bits instead of 32 bits.
do a rotation on such an emulated integer
Currently you can do a rotation, but the upper bits of the actual int which are not part of the emulated int can end up in something other than 0. Example:
intput x
0000 0000 0000 0000 0000 0000 0000 1100
|____|___, emulated int
result of rotating left by n=2 | |
0000 0000 0000 0000 0000 0000 0011 0011
As we can see, all we have to do is setting the bits above the emulated int (that is the 32 - BITS_IN_INTEGER upper bits) to zero. To this end, we use a logical "and" (&). We need a mask that has 0 on the bits we want to set to zero (anything & 0 is always 0) and a 1 on the bits we want to keep (anything & 1 is always anything).
0...0 0011 0011 ← the result from before
& 0...0 0000 1111 ← a mask
——————————————————
0...0 0000 0011 ← the masked result where unused bits are 0
To generate a mask of the form 0...01...1 with BITS_IN_INTEGER many 1s we can use (1 << BITS_IN_INTEGER) - 1. The - 1 converts 10000 into 01111.
static int BITS_IN_INTEGER = 4;
static int INTEGER_MASK = (1 << BITS_IN_INTEGER) - 1;
static int leftRotate(int x, int n) {
return INTEGER_MASK & ((x << n) | (x >>> (BITS_IN_INTEGER - n)));
}
This is a javascript implementation of leftRotate() and rightRotate(), based on the above Answer from Socowi (thank you!)
I needed to emulate a simple compass with 90º degree rotations in both left (counter-clockwise) and right (clockwise) directions (not a real compass, just a funny problem).
So instead of messing up the code by storing the previous orientation and using * if / else * or * switch *, I came up with the idea that a circular-shift or bit-rotation would be much more clean, efficient, and elegant of course.
However, I had the same problem about limiting the mask to 4 bits. Thanks to the above solution I was able to do it! ;)
So assuming the following:
- North = 1 = 0001
- West = 2 = 0010
- South = 4 = 0100
- East = 8 = 1000
When I need to turn 90º from North to -> West I call leftRotate() and so on until I get to the same point again (North).
The same applies in reverse, if turning 90º from North to -> East I call rightRotate(), and then again to turn South, and so on.
Here is the snippet, hope it helps:
const BITS_IN_INTEGER = 4;
const INTEGER_MASK = (1 << BITS_IN_INTEGER) - 1;
// this function rotates to left (counter clockwise) 1,2,4,8...1,2,4,8
function leftRotate(x, n) {
return INTEGER_MASK & ((x << n) | (x >>> (BITS_IN_INTEGER - n)));
}
// this function rotates to right (clockwise) 1,8,4,2...1,8,4,2
function rightRotate(x, n) {
return INTEGER_MASK & ((x << (BITS_IN_INTEGER - n)) | (x >>> n));
}
// Lets rotate:
console.log('--- Rotate to left (counter clockwise) 1,2,4,8...1,2,4,8...1:')
let value = 1;
for (let i = 0; i < 8; i++) {
console.log(value);
value = leftRotate(value, 1);
}
console.log('-- Rotate to right (counter clockwise) 1,8,4,2...1,8,4,2...1:')
for (let i = 0; i < 8; i++) {
console.log(value);
value = rightRotate(value, 1);
}

Java. Extracting integers from bits in a byte array not fitting the byte boundary

I have the following array of bytes:
01010110 01110100 00100101 01001011
These bytes are broken into two groups to encode seven integers. I know that the first group consists of 3 values 4 bits each (0101 0110 0111) that represent numbers 5,6,7. The second group consists of 4 values 5 bits each (01000 01001 01010 01011), which represent integers 8,9,10, and 11.
To extract the integers, I am currently using the following approach. Convert the array into a binary string:
public static String byteArrayToBinaryString(byte[] byteArray)
{
String[] arrayOfStrings = new String[byteArray.length];
for(int i=0; i<byteArray.length; i++)
{
arrayOfStrings[i] = byteToBinaryString(byteArray[i]);
}
String bitsetString = "";
for(String testArrayStringElement : arrayOfStrings)
{
bitsetString += testArrayStringElement;
}
return bitsetString;
}
// Taken from here: http://helpdesk.objects.com.au/java/converting-large-byte-array-to-binary-string
public static String byteToBinaryString(byte byteIn)
{
StringBuilder sb = new StringBuilder("00000000");
for (int bit = 0; bit < 8; bit++)
{
if (((byteIn >> bit) & 1) > 0)
{
sb.setCharAt(7 - bit, '1');
}
}
return sb.toString();
}
Then, I split the binary string into 2 substrings: 12 characters and 20 characters. Then I split each substring into new substrings, each of which has length that equals the number of bits. Then I convert each sub-substring into an integer.
It works but a byte array representing thousands of integers takes 30 seconds to a minute to extract.
I am a bit at a loss here. How do I do this using bitwise operators?
Thanks a lot!
I assume you have an understanding of the basic bit operations and how to express them in Java.
Use a pencil to draw a synthetic picture of the problem
byte 0 byte 1 byte 2 byte 3
01010110 01110100 00100101 01001011
\__/\__/ \__/\______/\___/\______/\___/
a b c d e f g
To extract a, b and c we need to do the following
a b c
byte 0 byte 0 byte 1
01010110 01010110 01110100
\. \. |||||||| \. \.
'\ '\ XXXX|||| '\ '\
0.. 0101 0.. 0110 0.. 0111
Shift And Shift
In Java
int a = byteArray[0] >>> 4, b = byteArray[0] & 0xf, c = byteArray[1] >>> 4;
The other values d, e, f and g are computed similarly but some of them require to read two bytes from the array (d and f actually).
d e
byte 1 byte 2 byte 2
01110100 00100101 00100101
||||\\\\ | |\\\\\
XXXX \\\\ | X \\\\\
\\\\| \\\\\
0.. 01000 01001
To compute d we need to isolate the least four bits of byte 1 with byteArray[1] & 0xf then make space for the bit from byte 2 with (byteArray[1] & 0xf) << 1, extract that bit with byteArray[1] >>> 7 and finally merge together the result.
int d = (byteArray[1] & 0xf) << 1 | byteArray[2] >>> 7;
int e = (byteArray[2] & 0x7c) >>> 2;
int f = (byteArray[2] & 0x3) << 3 | byteArray[3] >>> 5;
int g = byteArray[3] & 0x1f;
When you are comfortable with handling bits operations you may consider generalizing the function that extract the integers.
I made function int extract(byte[] bits, int[] sizes, int[] res), that given an array of bytes bits, an array of sizes sizes, where the even indices hold the size of the integers to extract in bits and the odd indices the number of integers to extract, and an output array res large enough to hold all the integers in output, extracts from bits all the integers expressed by sizes.
It returns the number of integers extracted.
For example the original problem can be solved as
int res[] = new int[8];
byte bits[] = new byte[]{0x56, 0x74, 0x25, 0x4b};
//Extract 3 integers of 4 bits and 4 integers of 5 bits
int ints = BitsExtractor.extract(bits, new int[]{4, 3, 5, 4}, res);
public class BitsExtractor
{
public static int extract(byte[] bits, int[] sizes, int[] res)
{
int currentByte = 0; //Index into the bits array
int intProduced = 0; //Number of ints produced so far
int bitsLeftInByte = 8; //How many bits left in the current byte
int howManyInts = 0; //Number of integers to extract
//Scan the sizes array two items at a time
for (int currentSize = 0; currentSize < sizes.length - 1; currentSize += 2)
{
//Size, in bits, of the integers to extract
int intSize = sizes[currentSize];
howManyInts += sizes[currentSize+1];
int temp = 0; //Temporary value of an integer
int sizeLeft = intSize; //How many bits left to extract
//Do until we have enough integer or we exhaust the bits array
while (intProduced < howManyInts && currentByte <= bits.length)
{
//How many bit we can extract from the current byte
int bitSize = Math.min(sizeLeft, bitsLeftInByte); //sizeLeft <= bitsLeftInByte ? sizeLeft : bitsLeftInByte;
//The value to mask out the number of bit extracted from
//The current byte (e.g. for 3 it is 7)
int byteMask = (1 << bitSize) - 1;
//Extract the new bits (Note that we extract starting from the
//RIGHT so we need to consider the bits left in the byte)
int newBits = (bits[currentByte] >>> (bitsLeftInByte - bitSize)) & byteMask;
//Create the new temporary value of the current integer by
//inserting the bits in the lowest positions
temp = temp << bitSize | newBits;
//"Remove" the bits processed from the byte
bitsLeftInByte -= bitSize;
//Is the byte has been exhausted, move to the next
if (bitsLeftInByte == 0)
{
bitsLeftInByte = 8;
currentByte++;
}
//"Remove" the bits processed from the size
sizeLeft -= bitSize;
//If we have extracted all the bits, save the integer
if (sizeLeft == 0)
{
res[intProduced++] = temp;
temp = 0;
sizeLeft = intSize;
}
}
}
return intProduced;
}
}
Well I did the first group , the second can be done in similar fashion
public static void main(String args[]) {
//an example 32 bits like your example
byte[] bytes = new byte[4];
bytes[0] = 31;//0001 1111
bytes[1] = 54;//0011 0110
bytes[2] = 67;
bytes[3] = 19;
//System.out.println(bytes[0]);
int x = 0;
int j = -1; // the byte number
int k = 0; // the bit number in that byte
int n = 0; // the place of the bit in the integer we are trying to read
for (int i = 0; i < 32; i++) {
if (i < 12) { //first group
if (i % 8 == 0) {
j++;
k = 0;
}
if (i % 4 == 0) {
x = 0;
n = 0;
}
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
System.out.println("j is :" + j + " k is :" + k + " " + bit);
x = x | bit << (3 - n);
if ((i + 1) % 4 == 0) {
System.out.println(x);
}
k++;
n++;
} else {
}
}
}
It's a bit tricky because you are trying to encode an integer on less than what java allocates (8 bits). So I had to take each bit and "construct" the int from them
To get each bit
byte bit = (byte) ((bytes[j] & (1 << (7 - k))) >> (7 - k));
this takes the byte we are at and does And operation. For example I want the 3rd bit of the 1st byte, I do
bytes[0] & 1 << (7 - 3)
but this gives me an integer encoded over 8 bits, so I still have to shift it to get that single bit with >> (7 - 3)
Then I just Or it with x (the int we are trying to decode). All while putting it at the right position with << (3 - n) . 3 because your integer is encoded over 4 bits
Try running the code and reading the output.
I am honestly not sure if this is the best way, but I believe it's at least faster than dealing with Strings

Understanding bitwise operations on a byte array

I am trying to develop a program to read certain type of file and extract all the package information of this file in bit level.
The packet is divided as:
SYC: 8 bits
TEI: 1 bits
PSI: 1 bit
TP: 1 bit
PID: 13 bits
TSC: 2 bits
AFC: 2 bits
CC: 4 bits
My question is: how do I get the bits separately? For example the PID, 5 bits are in position 1 of the array and 8 bits in position 2; how can I get this information from 2 separate bytes and sum them afterwards?
I have this sample code to get the PID and it reproduces the correct result:
int PID1 = (buf [1] << 8) | (buf [2] & 0xff);
I don't understand this equation, especially buf [1] << 8. Could someone explain to me this equation and what should I do to get the rest of the package information?
The '<<' operator moves the bits position to the right in binary which is essentially the same as multiplying by two.
This code :
byte buf[] = new byte[2];
buf[1] = 3;
for (int i = 0; i < 9; i++) {
int bshifted = buf[1]<<i;
System.out.println("buf[1]<<"+i+" = " + Integer.toBinaryString(bshifted) +"(binary) = "+ bshifted + "(decimal)");
}
Produces this output:
buf[1]<<0 = 11(binary) = 3(decimal)
buf[1]<<1 = 110(binary) = 6(decimal)
buf[1]<<2 = 1100(binary) = 12(decimal)
buf[1]<<3 = 11000(binary) = 24(decimal)
buf[1]<<4 = 110000(binary) = 48(decimal)
buf[1]<<5 = 1100000(binary) = 96(decimal)
buf[1]<<6 = 11000000(binary) = 192(decimal)
buf[1]<<7 = 110000000(binary) = 384(decimal)
buf[1]<<8 = 1100000000(binary) = 768(decimal)
The whole expression (buf [1] << 8) | (buf [2] & 0xff) has the effect of moving buf[1] out of the low order 8 bits of the int and putting only the low order 8 bits of buf[2] into that part of the integer.

Java - Bit Insertion

I have a long number like:
long l = Long.parseLong("10*000001111110" , 2) ;
Now, I want to add two bits in one position (say 2nd position, marked as *) into the long number.
Like,
long l = Long.parseLong("10*11*000001111110" , 2) ; (given between *)
Can anybody help me how to do that ? Note that I give an example to illustrate what I want. In real, I have only long land I have to work on it.
Edit:
1) position is not constant may be 0, 1 , 2 .. whatever.
2) and msb's can be 0. Means,
long l = Long.parseLong("00000010*000001111110" , 2) ;
long l = Long.parseLong("00000010*11*000001111110" , 2) ;
It sounds like you want something like bitStuffing where masking (&, ~, ^, and |) and shifting (>> and <<) are your instruments of choice.
long insertBit(long p_orignal, long p_new_bits, int p_starting_position_from_right, int p_ending_position_from_right)
{
long returnValue = p_original;
long onlyNewBits = 0;
// Set the bit to zero
long mask = (0xFFFFFFFFFFFFFFFFl);
for (int i=p_starting_position_from_right; i<=p_ending_position_from_right; i++)
{
mask ^ (1l << i);
}
returnValue = returnValue & mask;
mask = ~mask;
onlyNewBits = ~(p_new_bits & mask);
returnValue |= onlyNewBits;
return returnValue;
}
Disclaimer: I don't have a Java compiler available to compile this, but it should be something like this.
The first idea I had is the following:
Extract the first x bits that needs to stay on the position they are (in your example: 10) -> you could do this by running through a loop which creates the appropriate bitmask:
long bitmask = 1;
for(long bit = 1; bit < index; bit++) {
bitmask = (bitmask << 1) | 1;
}
Now you can create the long number that gets inserted -> just shift that number index positions to the left.
After that, you can easily build the new number:
long number = (((oldNumber >> index) << index) << insertionLength) | (insertion << index) | (oldNumber && bitmask);
Note: ((oldNumber >> index) << index) clears out the right part of the number (this part gets appended at the end using the bistmask). then you just need to shift this result by the length of the insertion (make space for it) and or it with the insertion (this needs to get shifted to the left by the index where to insert: (insertion << index). Finally, or the last part of the number (extracted via the bitmask: oldNumber && bitmask) to this result and you are done.
Note: I haven't tested this code. However, generally it should work but you may need to check my shifts (either it is index or index - 1 or so)!
If you only have the Long value say 123 you need to first convert this to a binary string. Like so:
String binaryValue = Long.toBinaryString("123L");
Then we take the string representation and perform a manipulation a specific character like so:
char[] characters = binaryValue.toCharArray();
char desiredCharacter = characters[index];
if(desiredCharacter == '1')
{
if(newValue == '1')
{
desiredCharacter = '0';
}
}else{
if(newValue == '1')
{
desiredCharacter ='1';
}
}
finally we convert the modified characters back into a string like so:
String rebuiltString = new String(characters);
I am sure there are more efficient ways to do this.
Well, if you want to set a specific bit in a number:
To turn it on:
number |= (1 << pos)
if pos = 4: (1<<pos) = 00000000 00000000 00000000 00010000
To turn it off:
number &= ~(1 << pos)
if pos = 4: ~(1<<pos) = 11111111 11111111 11111111 11101111
where pos is the position of the bit (with 0 being the low order bit, and 64 being the high order bit).

Java Bit Manipulation - What does (num >>= 1) do?

I was looking at some code that outputs a number to the binary form with prepended 0s.
byte number = 48;
int i = 256; //max number * 2
while( (i >>= 1) > 0) {
System.out.print(((number & i) != 0 ? "1" : "0"));
}
and didn't understand what the i >>= 1 does. I know that i >> 1 shifts to the right by 1 bit but didn't understand what the = does and as far as I know, it is not possible to do a search for ">>=" to find out what it means.
i >>= 1 is just shorhand for i = i >> 1 in the same way that i += 4 is short for i = i + 4
EDIT: Specifically, those are both examples of compound assignment operators.

Categories