Finding out number of bits that have changed (bitwise operator) - java

I have a bit string that is generated based on user input. I also have another bit string that I use to perform bitwise & with the generated bit string. What I would like to know is how to find out how many bits of the generated bit string has changed from the & operation. So let say if I have 10000101 as generated bit string and 00101111 as a second bit string I use for & operation. The output of the process should be 1 since only the first bit of the generate bit string has changed. How do I do that?

What you are looking for is bitwise XOR (exclusively OR), or a^b:
10000101 ^ 00101111 → 10101010
Is is logically equivalent to (~a&b) | (a&~b)

You need to XOR the result with the original to identify which bits were changed:
changedBits = (userInput & generatedInput) ^ userInput
Then, you need to calculate the Hamming Weight of the changedBits value:
int hammingWeight(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
return (((i + (i >>> 4)) & 0x0F0F0F0F) * 0x01010101) >>> 24;
}
int numberOfChangedBits = hammingWeight(changedBits);
Adjust as needed depending on how many bits your inputs are.

Related

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

Unique ID generation Algorithm

I have found an code in my project for generation of PKs and I simply cannot understand what this code do.
Can anyone give me some directions or ideas or explanation?
Integer typecode = ((AbstractEntity)object).getTypeCode();//this is unique number for every type
Long counter = Long.valueOf(this.fetchNextCounter(typecode.intValue())); //this returns a counter for each type
Integer clusterid = Integer.valueOf(0);
Integer millicnt = Integer.valueOf(0);
Long creationtime = Long.valueOf((new DateTime()).getMillis());
//here is where the magic starts and I cant simply understand a thing
if(typecode.intValue() >= 0 && typecode.intValue() <= 32767) {
long longValue = counter.longValue() << 15 | (long)typecode.intValue() << 48 & -281474976710656L;
longValue += ((long)clusterid.intValue() & 15L) << 44 & 263882790666240L;
longValue += creationtime.longValue() - 788914800000L << 4 & 17592186044400L;
longValue += (long)(clusterid.intValue() >> 2) & 12L;
longValue += (long)millicnt.intValue() & 3L;
longValue &= -8796093022209L;
return Long.valueOf(longValue);
} else {
throw new RuntimeException("illegal typecode : " + typecode + ", allowed range: 0-" + 32767);
}
I would appreciate everyone who can help? The problem we have is that we have typecodes which are bigger then 32767 and as the algorithm shows this doesn't work but why and how can we change it?
Line by line (with added clarifying parentheses):
long longValue = counter.longValue() << 15 | (((long)typecode.intValue() << 48) & -281474976710656L);
It computes the binary-OR of two values:
counter shifted left by 15 bits
typecode shifted left by 48 bits and applied the mask -281474976710656 (the same as 0xFFFF000000000000). This mask seems redundant.
-
longValue += (((long)clusterid.intValue() & 15L) << 44) & 263882790666240L;
It gets the last 4 bits of of clusterid (& 15, same as & 0xF) , shifts it left by 44 bits, then applies the mask 263882790666240L, that is the same as 0xF00000000000. This last mask apply seems to be redundant. Sums it to the result.
longValue += ((creationtime.longValue() - 788914800000L) << 4) & 17592186044400L;
It subtracts the creationtime by 788914800000L (that is the timestamp for 12/31/1994 # 11:00pm (UTC)), shifts 4 bits left, then applies the mask 17592186044400L, that is the same as 0xFFFFFFFFFF0. Sums it to the result.
longValue += (long)(clusterid.intValue() >> 2) & 12L;
Then it gets the cluster id, discards the last 2 bits (>> 2) and applies the mask 12L, that is the same as getting the 3rd and 4th bits (5th and 6th in the original number). Sums it to the result.
longValue += (long)millicnt.intValue() & 3L;
It gets the last 2 bits of millicnt (& 3L). Sums it to the result.
longValue &= -8796093022209L;
Then it applies the the mask -8796093022209L to the reslt, that is the same as 0xFFFFF7FFFFFFFFFF. It in practice zeroes the 44th bit of the resulting number.
The operators <<, >>, | and & are all bitwise operators. The act on the individual bits of the underlying binary value of those numbers. For more information, give this article a read. And then take a sample value and work through the code.
This bit of code is putting parts of the bit representation of the typecode, counter, longvalue, creationtime, clusterid and millicnt after each other. This creates a new number that is unique because the combination of all the above is unique. However the way the values are packed in does mean that you can't have more then 32767 typecodes. There just isn't enough space.
You can see the process in detail by using Long.toBinaryString() to see the bit representations of the input and the longValue after each step.
Since these are primary keys for a database I reckon you can let the database generate the key for you though.

bitwise right shift and 0xFF | Java

I am trying to understand a piece of code but not able to get clear idea about few points
here is the Java code
private String firstMethod(int number){
return secondMethod(number >> 16 & 0xFF, 0).concat(secondMethod(number >> 8 & 0xFF, 1)).concat(secondMethod(number & 0xFF, 7));
}
private static String secondMethod(int value, int offset)
{
return thirdMethod(value >> 4, offset).concat(thirdMethod(value & 0xF, offset + 4));
}
private static String thirdMethod(int value, int offset)
{
String chars = getAlphabet();
int pos = (value + offset) % 16;
return chars.substring(pos, pos + 1);
}
value passed to firstMethod is a random number for first time and all subsequent call to method will pass value incremented by 1.
I am clear about bit-wise right shift operation as well about the use of & 0xFF, however I am still not very clear about following points
Shifting given value by specific number (like 16 and 8 for first than no sift etc)
Not clear about use of offset ,specifically passing certain number as offset.
Can anyone help me to understand those 2 point
Shifting given value by specific number (like 16 and 8 for first than no sift etc)
You are printing bytes as hexi-decimal. Each byte is 8-bits so you want to shift each byte by
Not clear about use of offset ,specifically passing certain number as offset.
I am pretty sure the offset is either a) incorrect, b) a really obscure way of masking/encoding the data.
To print a number as a 6 byte hexi-decimal String you can do this.
System.out.println(String.format("%06x", 12345));
prints
003039
This is much shorter. ;)
>> has a surprising low precedence. This means
number >> 16 & 0xFF
is actually
number >> (16 & 0xFF)
or
number >> 16
what you indedn was
(number >> 16) & 0xFF
or as the result is unsigned.
(number >>> 16) & 0xFF
An integer is a 32-Bit Number.
So as a binary-number, you can represent number as:
XXXXXXXXAAAAAAAABBBBBBBBCCCCCCCC
(X, A, B, C stands for 0 or 1).
number >> 16 gives you XXXXXXXXAAAAAAAA.
number >> 16 & 0xFF gives you AAAAAAAA
By the firstMethod number is splited in 3 Bytes:
AAAAAAAA and BBBBBBBB and CCCCCCC (Shift of 16, shift of 8 and no shift)
and given to the secondMethod.
In the secondMethod the 8 Bits are splited in the higher four bits and the lower four bits.
In the thirdMethod the four Bits is translate to a String containing one char.
But the sense depends on "getAlphabet()".
Perhaps there will be also a usefull interpretation for the offset.
So you have to give further information!

How does the call to the hashing algorithm work, particularly the use of bit shifting 0xff?

The following code snippet, sourced from Core Java Vol 2 (7th Ed), shows how to create an SHA1 and an MD5 fingerprint using Java.
It turns out that the only function that works is when I load the cleartext from a textfile.
How does MessageDigestFrame.computeDigest() work out the fingerprint, and, particularly the use of the bit shifting pattern (Line 171 - 172)?
public void computeDigest(byte[] b)
{
currentAlgorithm.reset();
currentAlgorithm.update(b);
byte[] hash = currentAlgorithm.digest();
String d = "";
for (int i = 0; i < hash.length; i++)
{
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
}
digest.setText(d);
}
The method should work fine whatever you give it - if you're getting the wrong results, I suspect you're loading the file incorrectly. Please show that code, and we can help you work out what's going wrong.
In terms of the code, this line:
int v = hash[i] & 0xFF;
is basically used to treat a byte as unsigned. Bytes are signed in Java - an acknowledged design mistake in the language - but we want to print out the hex value as if it were an unsigned integer. The bitwise AND with just the bottom 8 bits effectively converts it to the integer value of the byte treated as unsigned.
(There are better ways to convert a byte array to a hex string, but that's a separate matter.)
It is not bit shifting, it is bit masking. hash[i] is a byte. When it is widened to integer you need to mask off the higher integer bits because of possible sign extension.
byte b = (byte)0xEF;
System.out.println("No masking: " + (int)b);
System.out.println("Masking: " + (int)(b & 0xFF));
This snipped:
int v = hash[i] & 0xFF;
if (v < 16) d += "0";
d += Integer.toString(v, 16).toUpperCase() + " ";
First you set all but the lowest 8 bits of v to 0 (because 0xFF is 11111111 in binary).
Then if the resulting number is only one digit in hex (< 16) you add a leading "0".
Finally convert the result to hex and add it to the string.

Removing lowest order bit

Given a binary number, what is the fastest way of removing the lowest order bit?
01001001010 -> 01001001000
It would be used in code to iterate over the bits of a variable. Pseudo-code follows.
while(bits != 0){
index = getIndexOfLowestOrderBit(bits);
doSomething(index);
removeLowestOrderBit(bits);
}
The possible languages I'm considering using are C and Java.
This is what I've got so far, I'm wondering if anyone can beat this.
bits &= bits-1
Uh ... In your example, you already know the bit's index. Then it's easy:
bits &= ~(1 << index);
This will mask off the bit whose index is index, regardless of its position in the value (highest, lowest, or in-between). Come to think of it, you can of course use the fact that you know the bit is already set, and use an XOR to knock it clear again:
bits ^= (1 << index);
That saves the inversion, which is probably one machine instruction.
If you instead want to mask off the lowest set bit, without knowing its index, the trick is:
bits &= (bits - 1);
See here for instance.
You can find the lowest set bit using x & (~x + 1). Example:
x: 01101100
~x+1: 10010100
--------
00000100
Clearing the lowest set bit then becomes x & ~(x & (~x + 1)):
x: 01101100
~(x&(~x+1)): 11111011
--------
01101000
Or x & (x - 1) works just as well and is easier to read.
The ever-useful Bit Twiddling Hacks has some algorithms for counting zero bits - that will help you implement your getIndexOfLowestOrderBit function.
Once you know the position of the required bit, flipping it to zero is pretty straightforward, e.g. given a bit position, create mask and invert it, then AND this mask against the original value
result = original & ~(1 << pos);
You don't want to remove the lowest order bit. You want to ZERO the lowest order SET bit.
Once you know the index, you just do 2^index and an exclusive or.
In Java use Integer.lowestOneBit().
I don't know if this is comparable fast, but I think it works:
int data = 0x44A;
int temp;
int mask;
if(data != 0) { // if not there is no bit set
temp = data;
mask = 1;
while((temp&1) == 0) {
mask <<= 1;
temp >>= 1;
}
mask = ~mask;
data &= mask;
}

Categories

Resources