Getting a negative number for a long - java

I am using this hashing algorithm..
public long DEKHash(String str)
{
long hash = str.length();
for(int i = 0; i < str.length(); i++)
{
hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);
}
return hash;
}
I have modified it slightly so that it produces a larger number. But this number is larger than a long and then overflows and becomes negative. I am beginning Java and wanted to know if it is possible to get the real value?
I was looking into BigInteger but I am not having any luck with it.

Perhaps this will solve your problem. Use Long.unsignedCompare().
long a1 = 1;
long a2 = -1;
if (a2 < a1) {
// a2 is less which is what you would expect
System.out.println(a2);
}
if (Long.compareUnsigned(a1,a2) < 0) {
// here, a1 is less
System.out.println(a1);
}
prints
-1
1
Also, above you have
hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i);
Did you know that >> extends the sign bit to the right. If you want to just right shift and not extend (i.e. fill with 0 bits, then do >>>)

Related

Is there any java built-in method to get parity of Integer?

I was working on Bit manipulation lessons. And I found the c++ built-in functions such as __builtin_clz(),__builtin_popcount(),__builtin_parity().
I got all alternative java methods for set bits and trailing zeroes. For parity, I didn't find any method.
I did something like this.
int val = 0b100011;
System.out.println(Integer.bitCount(val)%2==0?"Even":"ODD");
Is there any efficient way to do this?
There is no built in method to get the parity of an integer.
I'm not sure what you mean by efficient, but in terms of time complexity your solution is O(1).
Another solution is to use something like this which is also constant time complexity (taken from the link above, but also similar to the book Hacker's Delight):
static boolean hasEvenParity(int x)
{
int y = x ^ (x >> 1);
y = y ^ (y >> 2);
y = y ^ (y >> 4);
y = y ^ (y >> 8);
y = y ^ (y >> 16);
// Rightmost bit of y holds the parity value
// if (y&1) is 1 then parity is odd else even
return (y & 1) == 0;
}
You can use the following method to find parity as there is no built-in function to do the same. A number is said to have odd parity if it contains odd number of 1s. Otherwise it is said to have even parity.
public static String findParity(int x){
boolean isOdd = false;
while(x != 0) {
isOdd = !isOdd;
x= x& (x-1);
}
return (isOdd)?"odd":"even";
}
You can also do it using a BitSet. And you can also pass in Strings.
int v = 292229202;
BitSet bs = BitSet.valueOf(new long[] { v
});
// number of bits set to 1.
System.out.println(bs.cardinality());
String s = "To be or not to be that is the question.";
BitSet bs1 = BitSet.valueOf(s.getBytes());
System.out.println(bs1.cardinality());
String parity = (bs1.cardinality() & 1) == 1 ? "odd" : "even";
And then there's the basic technique of iteration.
int sum = 0;
for (byte b : s.getBytes()) {
while (b != 0) {
sum += (b & 1);
b >>>= 1;
}
}
System.out.println((sum & 1) == 1 ? "odd"
: "even");

JAVA CRC16 function returns a 3 characters response instead of 4

I have a Java CRC16 function like below and I need it to return a 4 length alphanumeric result. But sometimes it returns only a 3 length alphanumeric. Why? I am cross comparing this CRC with a C application that calculates the CRC and usually it is the same CRC but from time to time the JAVA returns a 3 character result which raises an exception. Why?
int crrc = 0xFFFF; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
String str = "0009";
byte []by = x; // x is the byte array from args
for (byte b : by) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7-i) & 1) == 1);
boolean c15 = ((crrc >> 15 & 1) == 1);
crrc <<= 1;
if (c15 ^ bit) crrc ^= polynomial;
}
}
crrc &= 0xffff;
System.out.println(crrc);
System.out.println("CRC16-CCITT = " + Integer.toHexString(crrc) + " " + Integer.toHexString(crrc).length());
You're receiving ArrayIndexOutOfBoundException probably, so I think the hex value might have zero in its most significant nibble. Try to find out those values(x) and check whether (x >>> 12) == 0 or (x & 0xf000) == 0. If this returns true, you can pad your string with necessary number of 0s from the left.
One possible way: String.format("%04d", crrc)

Inverse function of Java's Random function

Java's Random function takes a seed and produces the a sequence of 'psuedo-random' numbers.
(It is implemented based on some algorithm discussed in Donald Knuth, The Art of Computer Programming, Volume 3, Section 3.2.1.), but the article is too technical for me to understand)
Is there an inverse function of it?
That is, given a sequence of numbers, would it be possible to mathematically determine what the seed would be?
(, which means, brute-forcing doesn't count as a valid method)
[Edit]
There seems to be quite a number of comments here... I thought I'd clarify what I am looking for.
So for instance, the function y = f(x) = 3x has an inverse function, which is y = g(x) = x/3.
But the function z = f(x, y) = x * y does not have an inverse function, because (I could give a full mathematical proof here, but I don't want to sidetrack my main question), intuitively speaking, there are more than one pair of (x, y) such that (x * y) == z.
Now back to my question, if you say the function is not inversible, please explain why.
(And I am hoping to get answers from those who have really read to article and understand it. Answers like "It's just not possible" aren't really helping)
If we're talking about the Oracle (née Sun) implementation of java.util.Random, then yes, it is possible once you know enough bits.
Random uses a 48-bit seed and a linear congruential generator. These are not cryptographically safe generators, because of the tiny state size (bruteforceable!) and the fact that the output just isn't that random (many generators will exhibit small cycle length in certain bits, meaning that those bits can be easily predicted even if the other bits seem random).
Random's seed update is as follows:
nextseed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
This is a very simple function, and it can be inverted if you know all the bits of the seed by calculating
seed = ((nextseed - 0xBL) * 0xdfe05bcb1365L) & ((1L << 48) - 1)
since 0x5DEECE66DL * 0xdfe05bcb1365L = 1 mod 248. With this, a single seed value at any point in time suffices to recover all past and future seeds.
Random has no functions that reveal the whole seed, though, so we'll have to be a bit clever.
Now, obviously, with a 48-bit seed, you have to observe at least 48 bits of output or you clearly don't have an injective (and thus invertible) function to work with. We're in luck: nextLong returns ((long)(next(32)) << 32) + next(32);, so it produces 64 bits of output (more than we need). Indeed, we could probably make do with nextDouble (which produces 53 bits), or just repeated calls of any other function. Note that these functions cannot output more than 248 unique values because of the seed's limited size (hence, for example, there are 264-248 longs that nextLong will never produce).
Let's specifically look at nextLong. It returns a number (a << 32) + b where a and b are both 32-bit quantities. Let s be the seed before nextLong is called. Then, let t = s * 0x5DEECE66DL + 0xBL, so that a is the high 32 bits of t, and let u = t * 0x5DEECE66DL + 0xBL so that b is the high 32 bits of u. Let c and d be the low 16 bits of t and u respectively.
Note that since c and d are 16-bit quantities, we can just bruteforce them (since we only need one) and be done with it. That's pretty cheap, since 216 is only 65536 -- tiny for a computer. But let's be a bit more clever and see if there's a faster way.
We have (b << 16) + d = ((a << 16) + c) * 0x5DEECE66DL + 11. Thus, doing some algebra, we obtain (b << 16) - 11 - (a << 16)*0x5DEECE66DL = c*0x5DEECE66DL - d, mod 248. Since c and d are both 16-bit quantities, c*0x5DEECE66DL has at most 51 bits. This usefully means that
(b << 16) - 11 - (a << 16)*0x5DEECE66DL + (k<<48)
is equal to c*0x5DEECE66DL - d for some k at most 6. (There are more sophisticated ways to compute c and d, but because the bound on k is so tiny, it's easier to just bruteforce).
We can just test all the possible values for k until we get a value whos negated remainder mod 0x5DEECE66DL is 16 bits (mod 248 again), so that we recover the lower 16 bits of both t and u. At that point, we have a full seed, so we can either find future seeds using the first equation, or past seeds using the second equation.
Code demonstrating the approach:
import java.util.Random;
public class randhack {
public static long calcSeed(long nextLong) {
final long x = 0x5DEECE66DL;
final long xinv = 0xdfe05bcb1365L;
final long y = 0xBL;
final long mask = ((1L << 48)-1);
long a = nextLong >>> 32;
long b = nextLong & ((1L<<32)-1);
if((b & 0x80000000) != 0)
a++; // b had a sign bit, so we need to restore a
long q = ((b << 16) - y - (a << 16)*x) & mask;
for(long k=0; k<=5; k++) {
long rem = (x - (q + (k<<48))) % x;
long d = (rem + x)%x; // force positive
if(d < 65536) {
long c = ((q + d) * xinv) & mask;
if(c < 65536) {
return ((((a << 16) + c) - y) * xinv) & mask;
}
}
}
throw new RuntimeException("Failed!!");
}
public static void main(String[] args) {
Random r = new Random();
long next = r.nextLong();
System.out.println("Next long value: " + next);
long seed = calcSeed(next);
System.out.println("Seed " + seed);
// setSeed mangles the input, so demangle it here to get the right output
Random r2 = new Random((seed ^ 0x5DEECE66DL) & ((1L << 48)-1));
System.out.println("Next long value from seed: " + r2.nextLong());
}
}
I normally wouldn't just link articles... But I found a site where someone looks into this in some depth and thought it was worth posting. http://jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html
It seems that you can calculate a seed this way:
seed = (seed * multiplier + addend) mod (2 ^ precision)
where multiplier is 25214903917, addend is 11, and precision is 48 (bits). You can't calculate what the seed was with only 1 number, but you can with 2.
EDIT: As nhahtdh said there's a part 2 where he delves into more of the math behind the seeds.
I would like to present an implementation to reverse a sequence of integers generated by nextInt().
The program will brute force on the lower 16-bit discarded by nextInt(), use the algorithm provided in the blog by James Roper to find previous seed, then check that upper 32 bit of the 48-bit seed are the same as the previous number. We need at least 2 integers to derive the previous seed. Otherwise, there will be 216 possibilities for the previous seed, and all of them are equally valid until we have at least one more number.
It can be extended for nextLong() easily, and 1 long number is enough to find the seed, since we have 2 pieces of upper 32-bit of the seed in one long, due to the way it is generated.
Note that there are cases where the result is not the same as what you set as secret seed in the SEED variable. If the number you set as secret seed occupies more than 48-bit (which is the number of bits used for generating random numbers internally), then the upper 16 bits of 64 bit of long will be removed in the setSeed() method. In such cases, the result returned will not be the same as what you have set initially, it is likely that the lower 48-bit will be the same.
I would like to give most the credit to James Roper, the author of this blog article which makes the sample code below possible:
import java.util.Random;
import java.util.Arrays;
class TestRandomReverse {
// The secret seed that we want to find
private static long SEED = 782634283105L;
// Number of random numbers to be generated
private static int NUM_GEN = 5;
private static int[] genNum(long seed) {
Random rand = new Random(seed);
int arr[] = new int[NUM_GEN];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt();
}
return arr;
}
public static void main(String args[]) {
int arr[] = genNum(SEED);
System.out.println(Arrays.toString(arr));
Long result = reverse(arr);
if (result != null) {
System.out.println(Arrays.toString(genNum(result)));
} else {
System.out.println("Seed not found");
}
}
private static long combine(int rand, int suffix) {
return (unsignedIntToLong(rand) << 16) | (suffix & ((1L << 16) - 1));
}
private static long unsignedIntToLong(int num) {
return num & ((1L << 32) - 1);
}
// This function finds the seed of a sequence of integer,
// generated by nextInt()
// Can be easily modified to find the seed of a sequence
// of long, generated by nextLong()
private static Long reverse(int arr[]) {
// Need at least 2 numbers.
assert (arr.length > 1);
int end = arr.length - 1;
// Brute force lower 16 bits, then compare
// upper 32 bit of the previous seed generated
// to the previous number.
for (int i = 0; i < (1 << 16); i++) {
long candidateSeed = combine(arr[end], i);
long previousSeed = getPreviousSeed(candidateSeed);
if ((previousSeed >>> 16) == unsignedIntToLong(arr[end - 1])) {
System.out.println("Testing seed: " +
previousSeed + " --> " + candidateSeed);
for (int j = end - 1; j >= 0; j--) {
candidateSeed = previousSeed;
previousSeed = getPreviousSeed(candidateSeed);
if (j > 0 &&
(previousSeed >>> 16) == unsignedIntToLong(arr[j - 1])) {
System.out.println("Verifying: " +
previousSeed + " --> " + candidateSeed);
} else if (j == 0) {
// The XOR is done when the seed is set, need to reverse it
System.out.println("Seed found: " + (previousSeed ^ MULTIPLIER));
return previousSeed ^ MULTIPLIER;
} else {
System.out.println("Failed");
break;
}
}
}
}
return null;
}
private static long ADDEND = 0xBL;
private static long MULTIPLIER = 0x5DEECE66DL;
// Credit to James Roper
// http://jazzy.id.au/default/2010/09/21/cracking_random_number_generators_part_2.html
private static long getPreviousSeed(long currentSeed) {
long seed = currentSeed;
// reverse the addend from the seed
seed -= ADDEND; // reverse the addend
long result = 0;
// iterate through the seeds bits
for (int i = 0; i < 48; i++)
{
long mask = 1L << i;
// find the next bit
long bit = seed & mask;
// add it to the result
result |= bit;
if (bit == mask)
{
// if the bit was 1, subtract its effects from the seed
seed -= MULTIPLIER << i;
}
}
return result & ((1L << 48) - 1);
}
}

Why are two different results returned when using following two shift operator statements in Java

When:
byte[] b = {-128, 0, 0, 0};
long total = 0;
The first expression returns -2,147,483,648:
for (int i = 0; i < b.length; i++) {
int shift = (b.length - 1 - i) * 8;
total += (b[i] & 255) << shift;
}
The second returns 2,147,483,648:
for (int i = 0; i < b.length; i++) {
int shift = (b.length - 1 - i) * 8;
long tmp = (b[i] & 255);
total += tmp << shift;
}
My question is; why is the first statement positive and the second negative when they appear to be the same statement?
In this line
total += (b[i] & 255) << shift;
the parenthesized expression is of type int and the left shift sets its leftmost bit to one, making it a negative number. The conversion to long happens only after all the calculation is done.
long tmp = (b[i] & 255);
Here the expression is long and the leftmost bit will stay zero after the shift.
If you want to keep the first expression, just add a cast to long for the parenthesized expression or use a long constant 255L.
shifting an int into the sign bit results in a negative number
shifting a long by the same amount results in a positive number
If you run the following code you may understand what is going on :
System.out.println(Integer.toBinaryString(-2147483648));
System.out.println(Long.toBinaryString(2147483648L));
It prints
10000000000000000000000000000000
10000000000000000000000000000000
The same bits are interpreted differently for long and int.

Bitwise operator for simply flipping all bits in an integer?

I have to flip all bits in a binary representation of an integer. Given:
10101
The output should be
01010
What is the bitwise operator to accomplish this when used with an integer? For example, if I were writing a method like int flipBits(int n);, what would go in the body? I need to flip only what's already present in the number, not all 32 bits in the integer.
The ~ unary operator is bitwise negation. If you need fewer bits than what fits in an int then you'll need to mask it with & after the fact.
Simply use the bitwise not operator ~.
int flipBits(int n) {
return ~n;
}
To use the k least significant bits, convert it to the right mask.
(I assume you want at least 1 bit of course, that's why mask starts at 1)
int flipBits(int n, int k) {
int mask = 1;
for (int i = 1; i < k; ++i)
mask |= mask << 1;
return ~n & mask;
}
As suggested by Lưu Vĩnh Phúc, one can create the mask as (1 << k) - 1 instead of using a loop.
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return ~n & mask;
}
There is a number of ways to flip all the bit using operations
x = ~x; // has been mentioned and the most obvious solution.
x = -x - 1; or x = -1 * (x + 1);
x ^= -1; or x = x ^ ~0;
Well since so far there's only one solution that gives the "correct" result and that's.. really not a nice solution (using a string to count leading zeros? that'll haunt me in my dreams ;) )
So here we go with a nice clean solution that should work - haven't tested it thorough though, but you get the gist. Really, java not having an unsigned type is extremely annoying for this kind of problems, but it should be quite efficient nonetheless (and if I may say so MUCH more elegant than creating a string out of the number)
private static int invert(int x) {
if (x == 0) return 0; // edge case; otherwise returns -1 here
int nlz = nlz(x);
return ~x & (0xFFFFFFFF >>> nlz);
}
private static int nlz(int x) {
// Replace with whatever number leading zero algorithm you want - I can think
// of a whole list and this one here isn't that great (large immediates)
if (x < 0) return 0;
if (x == 0) return 32;
int n = 0;
if ((x & 0xFFFF0000) == 0) {
n += 16;
x <<= 16;
}
if ((x & 0xFF000000) == 0) {
n += 8;
x <<= 8;
}
if ((x & 0xF0000000) == 0) {
n += 4;
x <<= 4;
}
if ((x & 0xC0000000) == 0) {
n += 2;
x <<= 2;
}
if ((x & 0x80000000) == 0) {
n++;
}
return n;
}
faster and simpler solution :
/* inverts all bits of n, with a binary length of the return equal to the length of n
k is the number of bits in n, eg k=(int)Math.floor(Math.log(n)/Math.log(2))+1
if n is a BigInteger : k= n.bitLength();
*/
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return n ^ mask;
}
One Line Solution
int flippingBits(int n) {
return n ^ ((1 << 31) - 1);
}
I'd have to see some examples to be sure, but you may be getting unexpected values because of two's complement arithmetic. If the number has leading zeros (as it would in the case of 26), the ~ operator would flip these to make them leading ones - resulting in a negative number.
One possible workaround would be to use the Integer class:
int flipBits(int n){
String bitString = Integer.toBinaryString(n);
int i = 0;
while (bitString.charAt(i) != '1'){
i++;
}
bitString = bitString.substring(i, bitString.length());
for(i = 0; i < bitString.length(); i++){
if (bitString.charAt(i) == '0')
bitString.charAt(i) = '1';
else
bitString.charAt(i) = '0';
}
int result = 0, factor = 1;
for (int j = bitString.length()-1; j > -1; j--){
result += factor * bitString.charAt(j);
factor *= 2;
}
return result;
}
I don't have a java environment set up right now to test it on, but that's the general idea. Basically just convert the number to a string, cut off the leading zeros, flip the bits, and convert it back to a number. The Integer class may even have some way to parse a string into a binary number. I don't know if that's how the problem needs to be done, and it probably isn't the most efficient way to do it, but it would produce the correct result.
Edit: polygenlubricants' answer to this question may also be helpful
I have another way to solve this case,
public static int complementIt(int c){
return c ^ (int)(Math.pow(2, Math.ceil(Math.log(c)/Math.log(2))) -1);
}
It is using XOR to get the complement bit, to complement it we need to XOR the data with 1, for example :
101 XOR 111 = 010
(111 is the 'key', it generated by searching the 'n' square root of the data)
if you are using ~ (complement) the result will depend on its variable type, if you are using int then it will be process as 32bit.
As we are only required to flip the minimum bits required for the integer (say 50 is 110010 and when inverted, it becomes 001101 which is 13), we can invert individual bits one at a time from the LSB to MSB, and keep shifting the bits to the right and accordingly apply the power of 2. The code below does the required job:
int invertBits (int n) {
int pow2=1, int bit=0;
int newnum=0;
while(n>0) {
bit = (n & 1);
if(bit==0)
newnum+= pow2;
n=n>>1;
pow2*=2;
}
return newnum;
}
import java.math.BigInteger;
import java.util.Scanner;
public class CodeRace1 {
public static void main(String[] s) {
long input;
BigInteger num,bits = new BigInteger("4294967295");
Scanner sc = new Scanner(System.in);
input = sc.nextInt();
sc.nextLine();
while (input-- > 0) {
num = new BigInteger(sc.nextLine().trim());
System.out.println(num.xor(bits));
}
}
}
The implementation from openJDK, Integer.reverse():
public static int More ...reverse(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
Base on my experiments on my laptop, the implementation below was faster:
public static int reverse2(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i & 0x00ff00ff) << 8 | (i >>> 8) & 0x00ff00ff;
i = (i & 0x0000ffff) << 16 | (i >>> 16) & 0x0000ffff;
return i;
}
Not sure what's the reason behind it - as it may depends on how the java code is interpreted into machine code...
If you just want to flip the bits which are "used" in the integer, try this:
public int flipBits(int n) {
int mask = (Integer.highestOneBit(n) << 1) - 1;
return n ^ mask;
}
public static int findComplement(int num) {
return (~num & (Integer.highestOneBit(num) - 1));
}
int findComplement(int num) {
int i = 0, ans = 0;
while(num) {
if(not (num & 1)) {
ans += (1 << i);
}
i += 1;
num >>= 1;
}
return ans;
}
Binary 10101 == Decimal 21
Flipped Binary 01010 == Decimal 10
One liner (in Javascript - You could convert to your favorite programming language )
10 == ~21 & (1 << (Math.floor(Math.log2(21))+1)) - 1
Explanation:
10 == ~21 & mask
mask : For filtering out all the leading bits before the significant bits count (nBits - see below)
How to calculate the significant bit counts ?
Math.floor(Math.log2(21))+1 => Returns how many significant bits are there (nBits)
Ex:
0000000001 returns 1
0001000001 returns 7
0000010101 returns 5
(1 << nBits) - 1 => 1111111111.....nBits times = mask
It can be done by a simple way, just simply subtract the number from the value
obtained when all the bits are equal to 1 .
For example:
Number: Given Number
Value : A number with all bits set in a given number.
Flipped number = Value – Number.
Example :
Number = 23,
Binary form: 10111
After flipping digits number will be: 01000
Value: 11111 = 31
We can find the most significant set bit in O(1) time for a fixed size integer. For
example below code is for a 32-bit integer.
int setBitNumber(int n)
{
n |= n>>1;
n |= n>>2;
n |= n>>4;
n |= n>>8;
n |= n>>16;
n = n + 1;
return (n >> 1);
}

Categories

Resources