Bit shifting for >32 bit long - java

I am trying to extract the first 49 bits from a 7 byte array. I approached this byte using masks and bit shifting as follows:
long byteVal = ((decryptedVCW[6] & 0xff)&((decryptedVCW[6] & 0xff)<<7)) | ((decryptedVCW[5] & 0xff) << 8) | ((decryptedVCW[4] & 0xff) << 16) | ((decryptedVCW[3] & 0xff) << 24) | ((decryptedVCW[2] & 0xff) << 32) | ((decryptedVCW[1] & 0xff) << 40) | ((decryptedVCW[0] & 0xff) << 48);
Where decryptedVCW is a 56 bit byte array.
The masking and bit shifting work as expected until the 32 bit shift '<<32'.
As an example, the hex for decryptedVCW is E865037A9C6424 of which in binary is:
11101000011001010000001101111010100111000110010000100100
When I perform the above shifting I get 7AFC6503 in binary:
1111010111111000110010100000011
Does anyone have any idea why the bit shifting falls apart at 32 upwards and how to go about solving this issue?
Many thanks
Shiv

The type of decryptedVCW[2] & 0xff is int, since the first operand is byte and the second is an int literal.
When the first operand of the << operator is int, you are shifting an int, so if the second operand is 32, you'll get int overflow.
You can cast the first operand of the << operator to long :
(((long)(decryptedVCW[2] & 0xff)) << 32)
or you can force the first operand to be a long by using a long literal in the & operation, as suggested by #shmosel :
(decryptedVCW[2] & 0xFFL) << 32

Related

How to convert one byte and 4 bits from another byte to a short using bitwise?

Using bitwise, how could we convert these 3 bytes to two shorts in this pattern in the most performant way?:
(11111111)(01111110)(10000001) 3 bytes
(111111110111)(111010000001) 2 shorts
Found a way to combine two bytes into a short, but for a combination of 1 byte and 4 bits tried a variety of ways for hours with no success. Thanks for your help.
byte byt1 = -1; // 11111111
byte byt2 = 126;// 01111110
byte byt3 = 129;// 10000001
short s_1_2 = (short) ((byt1 << 8) | (byt2 & 0xFF));
// value is 1111111101111110
short s1 = // want to be 111111110111
short s2 = // want to be 111010000001
One of the possibilities is the following:
short s1 = (short) (((byt1 & 0xff) << 4) | ((byt2 & 0xf0) >> 4));
short s2 = (short) (((byt2 & 0x0f) << 8) | (byt3 & 0xff));

Android 8 bit to 16 bit representation for Negative Numbers

Refer to the question How to Convert two 8 bit represented byte to single 16 bit represented integer value in Android.
I got an answer like this
short yourinteger16 = (short)(((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF));
This answer is correct for the positive number. But in the case of the negative number, it's failing.
For example, I am sending the value from the BLE to the application as -10. The value will convert from the BLE as -10000 because of mAh/mV conversion of current and voltage. These values are split into two bytes and I am getting the byte value as -39 and -16 in my application. I am passing the byte to the method as like below.
short yourinteger16 = (short)(((-39 & 0xFF) << 8) | (-16 & 0xFF));
But I am getting the result as 9.77 as the float value of yourinteger16 .
Anyone has any idea about this?. Any solution please update me.
Full Code:
Integer ampValue = null;
if (mBleDataHashMap.containsKey(SuperMuttBleConst.RESP_I_HIGH) &&
mBleDataHashMap.containsKey(SuperMuttBleConst.RESP_I_LOW)) {
ampValue = get8ByteTo16Byte(mBleDataHashMap.get(SuperMuttBleConst.RESP_I_HIGH),
mBleDataHashMap.get(SuperMuttBleConst.RESP_I_LOW));
}
if (ampValue != null) {
float newAmp = ampValue.floatValue();
newAmp = newAmp/1000;
mAmpTextvw.setText("" + newAmp);
}
Method
protected Integer get8ByteTo16Byte(int firstValue, int secondValue) {
Short integerValue = (short)((((byte) firstValue & 0xFF) << 8) | ((byte) secondValue & 0xFF));
return new Integer(integerValue);
}
You're receiving -39 and -16 perfectly (the high and low bytes for -10000, respectively).
Use addition instead of ORing the high and low bytes.
Please try the following
short result = (short) (((short)(-39 & (byte)0xFF) << 8) + (short)(-16 & (byte)0xFF));
The negative low bytes is causing trouble for the high byte when dealing with 2's complement arithmetic.

What algorithm is used by eclipse to generate verison id in Serializable class?

Suppose here is my class :
class B implements Serializable {
private static final long serialVersionUID = -5186261241138469827L; // what algo is used to generate this
..........
}
What algorithm eclipse uses to generate serialVersionUID = -5186261241138469827L ?
Eclipse implements the relevant Java spec to compute Serialization ID.
In Eclipse, this is implemented by calculateSerialVersionId method in org.eclipse.jdt.internal.ui.text.correction.SerialVersionHashOperation class.
Java Object Serialization Specification Docs ,given that algo
The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:
long hash = ((sha[0] >>> 24) & 0xFF) |
((sha[0] >>> 16) & 0xFF) << 8 |
((sha[0] >>> 8) & 0xFF) << 16 |
((sha[0] >>> 0) & 0xFF) << 24 |
((sha[1] >>> 24) & 0xFF) << 32 |
((sha[1] >>> 16) & 0xFF) << 40 |
((sha[1] >>> 8) & 0xFF) << 48 |
((sha[1] >>> 0) & 0xFF) << 56;

convert four 32 bits ints to IP address in java

Using the code found here: https://libbits.wordpress.com/2011/05/17/check-if-ip-is-within-range-specified-in-cidr-in-java/
// Step 1. Convert IPs into ints (32 bits).
// E.g. 157.166.224.26 becomes 10011101 10100110 11100000 00011010
int addr = (( 157 << 24 ) & 0xFF000000)
| (( 166 << 16 ) & 0xFF0000)
| (( 224 << 8 ) & 0xFF00)
| ( 26 & 0xFF);
// Step 2. Get CIDR mask
int mask = (-1) << (32 - 10);
// Step 3. Find lowest IP address
int lowest = addr & mask;
// Step 4. Find highest IP address
int highest = lowest + (~mask);
I'm able to split a string into four ints and create boundaries for my IP range.
Now I want to be able to generate an ip that is between the highest and lowest values. For example:
given the range: 157.166.224.26/10 I get an address of -1650008038 my lowest ip address is -1652555776 and highest ip address is -1648361473. Now I need to generate a number that is between my lowest and highest and convert it back to four integers, this last part is where I'm lost at, I'm not sure how to convert -1648361473 to an ip address
That's pretty easy. Let say the IPv4 address is in the ipaddr variable, you can write something like that:
byte[] addr = new byte[4];
addr[0] = (ipaddr >> 24) & 0xFF;
addr[1] = (ipaddr >> 16) & 0xFF;
addr[2] = (ipaddr >> 8 ) & 0xFF;
addr[3] = ipaddr & 0xFF;
InetAddress inetAddr = InetAddress.getByAddress(addr);
The answer that Teetoo made above deserves some explanation.
Lets start with the first value:
(ipaddr >> 24) & 0xFF
When this is shifted down, the 8 bits representing the 157 are in the rightmost position of the resulting integer. However, since the value was initially negative, you would have 1's in 24 most significant bits, which would end up giving you a negative number. What you want is to 0 out all but those last 8 bits, hence the "& 0xFF". Another way to do this would be to right shift using the >>> operator which forces 0's into the most significant bits.
(ipaddr >>> 24)
now we move on to:
(ipaddr >> 16) & 0xFF
When you shift, you'll have the 16 leftmost bits set to 1 (due to shifting a negative number). Then you'll have the 8 bits representing the 157 and then the 8 bits representing 166. In this case, the >>> operator wouldn't help us because we still have the 157 in there. So the "& 0xFF" will 0 out all but the 8 bits for the 166.
Similarly for the last two values.
an addition to #Teetoo's answer.
let's ByteBuffer do the int to byte array magic
ByteBuffer bb = ByteBuffer.wrap (addr);
bb.putInt (iIP);
You can use
int addr = (157 << 24) | (166 << 16) | (224 << 8) | 26;
to reverse this.
byte[] addrAsBytes = { (byte) (addr >> 24), (byte) (addr >> 16),
(byte) (addr >> 8), (byte) addr };

Change bits value in Byte

I have some data in field type Byte ( I save eight inputs in Byte, every bit is one input ).
How to change just one input in that field ( Byte) but not to lose information about others ( example change seventh bit to one, or change sixth bit to zero )?
To set the seventh bit to 1:
b = (byte) (b | (1 << 6));
To set the sixth bit to zero:
b = (byte) (b & ~(1 << 5));
(The bit positions are effectively 0-based, so that's why the "seventh bit" maps to 1 << 6 instead of 1 << 7.)
Declare b as the primitive type byte:
byte b = ...;
Then you can use the compound assignment operators that combine binary operations and assignment (this doesn't work on Byte):
b |= (1 << bitIndex); // set a bit to 1
b &= ~(1 << bitIndex); // set a bit to 0
Without the assignment operator you would need a cast, because the result of the | and & operations is an int:
b = (byte) (b | (1 << bitIndex));
b = (byte) (b & ~(1 << bitIndex));
The cast is implicit in the compound assignment operators, see the Java Language Specification.
To set a bit use :
public final static byte setBit(byte _byte,int bitPosition,boolean bitValue)
{
if (bitValue)
return (byte) (_byte | (1 << bitPosition));
return (byte) (_byte & ~(1 << bitPosition));
}
To get a bit value use :
public final static Boolean getBit(byte _byte, int bitPosition)
{
return (_byte & (1 << bitPosition)) != 0;
}
Note that the "Byte" wrapper class is immutable, and you will need to work with "byte".
You really owe it to yourself to look into masking functions for and, or, and xor -- they allow you to simultaneously verify, validate, or change... one, some, or all of the bits in a byte structure in a single statement.
I'm not a java programmer by trade, but it's derived from C and a quick search online seemed to reveal support for those bitwise operations.
See this Wikipedia article for more information about this technique.

Categories