Question

I have this line below where byte[] shaBytes with value from a SHA1. The first four is added to result to a number which is used in a while loop. I'm trying to port an objC code to java while the line below results to a negative value such as -2063597568 after several iterations.

long tVar = (shaBytes[0]  << 24) + (shaBytes[1] << 16) + (shaBytes[2] << 8) + (shaBytes[3] << 3);

So basically, the while loop loops when

tVar > 0xFFFFFFFFL >> 11

In objC shaBytes is an unsigned char which is used as parameter in a CC_SHA1. In objC the code would loop up 700+ iterations while my port only 3 because tVar becomes negative.

Was it helpful?

Solution

Java doesn't have unsigned bytes. All Java integer types are signed. This means that the left shift of a negative byte will be negative:

byte b = -30;
long x = b << 24;
System.out.printf("x = %d\n", x);
// prints -503316480

On other hand if you convert byte to long everything'll turn out okay:

byte b = -30;
long x = (b & 0xffL) << 24;
System.out.printf("x = %d\n", x);
// prints 3791650816

To convert byte to "unsigned" (remember, there is no unsigned stuff in Java) long value use:

long tVar = ((shaBytes[0] & 0xffL) << 24) + ((shaBytes[1] & 0xffL) << 16) + etc

This'll work because Java long is 64-bit and can handle 24 left shift of 8-bit value without signed/unsigned problems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top