I have a native function (from a library) that does some work on uint8_t types (unsigned 8-bit number 0-255). The closest thing Java has is byte which must be signed.
How can I convert this byte into a proper positive integer to use in Java? I know I'll have to store it in a short or int in order to properly represent numbers from 0-255, but I don't know how to convert the byte.
I tried int intValue = byteValue & 0xFF;, but that is giving me unexpected results, so I suspect it's incorrect. Or that is correct and I am misunderstanding the expected results from the native library function. Would appreciate confirmation either way.
In Java, you can use a Guava library function to convert a byte to an int, treating it as unsigned: UnsignedBytes.toInt. So, if you returned the value of a C++ unsigned value as a byte to Java, you can then fix it up.
If you want to make it into an int and then return it to java as an int, that should be perfectly straightforward.
Related
I'm reading a file format that specifies some types are unsigned integers and shorts. When I read the values, I get them as a byte array. The best route to turning them into shorts/ints/longs I've seen is something like this:
ByteBuffer wrapped = ByteBuffer.wrap(byteArray);
int x = wrapped.getInt();
That looks like it could easily overflow for unsigned ints. Is there a better way to handle this scenario?
Update: I should mention that I'm using Groovy, so I absolutely don't care if I have to use a BigInteger or something like that. I just want the maximum safety on keeping the value intact.
A 32bit value, signed or unsigned, can always be stored losslessly in an int*. This means that you never have to worry about putting unsigned values in signed types from a data safety point of view.
The same is true for 8bit values in bytes, 16bit values in shorts and 64bit values in longs.
Once you've read an unsigned value into the corresponding signed type, you can promote them to signed values of a larger types to more easily work with the intended value:
Integer.toUnsignedLong(int)
Short.toUnsignedInt(short)
Byte.toUnsignedInt(byte)
Since there's no primitive type larger than long, you can either go via BigInteger, or use the convenience methods on Long to do unsigned operations:
BigInteger.valueOf(Long.toUnsignedString(long))
Long.divideUnsigned(long,long) and friends
* This is thanks to the JVM requiring integer types to be two's complement.
To hold an unsigned int/short/byte, you need to use the next "bigger" type, i.e. long/int/short. If you already hold the value in the signed type that can overflow, the conversion can be done by doing the following:
int unsignedVal = byteVal & 0xff
If you just cast them, the negative-bit will be regarded and you will still end up with the negative value.
If you have to handle unsigned longs you need to "switch" to java.math.BigInteger.
Unsigned primitives are a pain in Java.
There's no clean way of handing them, except using larger types with more bits, and taking care to avoid automatic sign extension when casting.
In your case, you can do something like this:
ByteBuffer wrapped = ByteBuffer.wrap(byteArray);
int signedInt = wrapped.getInt();
long unsigned = signedInt & 0xffffffffL;
I usually write the required conversion(s) in a utility class someplace, since they're easy to get wrong. If you copy & paste that one liner conversion everywhere, eventually one will be wrong.
Note that if you need unsigned longs, the only larger type is BigInteger.
If you need anything more than simple conversions, I suggest using Guava since it has some nice classes for dealing with unsigned types. See documentation here.
I have a objective-c code.
but I want to convert to java code.
I know objective-c's NSData equals java's byte[].
but I don't know about the equivalent of rest of the keywords.
Objective-C CODE
NSData * updatedValue = characteristic.value;
uint8_t* dataPointer = (uint8_t*)[updatedValue bytes];
uint8_t flags = dataPointer[0]; dataPointer++;
int32_t tempData = (int32_t)CFSwapInt32LittleToHost(*(uint32_t*)dataPointer); dataPointer += 4;
int8_t exponent = (int8_t)(tempData >> 24);
int32_t mantissa = (int32_t)(tempData & 0x00FFFFFF);
if( tempData == 0x007FFFFF )
{
NSLog(#"Invalid temperature value received");
return;
}
float tempValue = (float)(mantissa*pow(10, exponent));
self.tempString = [NSString stringWithFormat:#"%.1f", tempValue];
Please help me
You could try
Objective c to Java converter
Incase if you need your java code to be converted to Objective C
Java to Objective c converter
Reference
Do not attempt convert it to Java, determine what it does and write it in Java.
A little educated guesswork based on your knowledge of programming should get you a long way to understanding the code. This is a great advantage of programming languages over natural languages, understand programming and you can usually make a good educated guess at the meaning of a fragment of code even if you don't know the language. In natural languages the same simply does not hold, knowing, say, French is little help in reading Hindi!
So let's see, uint8_t is probably a type, what type could it be? Well int sounds a lot like integer, 8 is probably the size of the integer in bits - it occurs in the second line which also contains the word bytes, and the u probably means unsigned. So guess that uint8_t is an unsigned 8-bit integer. Now look at the other type-like words, do they make sense in the same way?
So what is the code doing? Well you've figure out that NSData * is "like" byte[], so what would the code set flags to? The first byte in the array maybe? How about tempData? Well there is a 32 in the types here, and that is four bytes.
Having got tempData what do the code do? Some manipulation which results in tempValue which is a float. Maybe float is a 32-bit floating point number? Which is of course what it is in Java.
However here you're going to hit a wall. If you look up how a 32-bit floating-point number is represented in IEEE 754 - the most common way to represent floating point numbers - you will discover that it is stored in binary with the mantissa being a faction (see Wikipedia).
Now look at the code, pow(10, exponent) looks a lot like 10 to the power, not 2 to the power. And does the mantissa look like its being treated as a fraction?
So whatever for those 4 bytes you've guessed are being converted into a float it looks like either (a) they are not a typical 32-bit float or (b) the Objective-C code is wrong...
So back to the first point - determine what this code is meant to do and then write it directly in Java, don't try to convert it.
HTH
I am working on an Smart Card where there is a method in javax.smartcardio.CommandAPDU.
CommandAPDU(int cla, int ins, int p1, int p2, byte[] data, int ne)
I need to send data as byte[] (5th argument). Now my problem is that, as Java primitive data types are signed the max value of a byte can not exceed 127. I need to send a value bigger than 127. To be precise, the hex value 94 which is equal to 148.
As some solution suggests that we can cast it to integer.
byte b = -108;
int i = b & 0xff;
I can't do that as the CommandAPDU(); constructor doesn't take an []. So how to do it?
Depending on how it is interpreted by the smart card, you could just send the correct negative value. If the smart card interprets value as unsigned, you could for example send -1 for 255.
You're calculating the APDU with unsigned bytes, while Java uses signed bytes.
It's just a matter of how the data is interpreted, sending -108 to the smart card will be interpreted in exactly the same way as sending 148 from a platform using unsigned bytes. The bit combination is exactly the same.
Java can even do the conversion itself so that you can write the code using unsigned numbers;
byte data = (byte)0x94; // stores -108 in "data", which will be interpreted
// as 148 on an unsigned platform
For long blocks of data, it is probably best to use a hexadecimal encoder/decoder. But be sure that you handle the data as bytes internally (directly decode and don't look back to the hex String). The Apache codec library contains a good encoder/decoder, or you can use Bouncy Castle or Guava or use one of the many examples on SO.
I need to convert a piece of code from Objective-C to Java, but I have a problem understanding the Primitive Types in Objective-C. So I had their data types in my Objective-C code :
UInt64, Uint32, UInt8 ,
which are unsigned integers (as I understand from internet). So my question is, can I use Java primitive types like byte (8bit) - instead of UInt8, int (32bit) - instead of UInt32, and long (64bit) - instead of UInt64.
Unfortunately, it isn't a straight translation and without knowing more about your program, its hard to suggest what the "right" approach is.
If your UInt8 values really range from 0-255, you may have to use Java signed int to be able to hold the entire range.
If you are dealing with byte streams or memory layouts and really need to use just a single byte of memory, than you could try byte, but you may have to test and handle cases to handle when the high-bit is set (value > 127). Ditto with the other unsigned types.
Ideally, if your code just kind of "defaulted" to the unsigned types, but really the signed versions would have worked fine too (i.e. the ranges of your values never equal or exceed 2^7, 2^15, or 2^31 respectively), then you may be fine with the "straight" translation to byte, int, and long.
Yes, those are the correctly sized data types to use in Java. Make sure you take into account that Java does not have unsigned types and the trick is to use the next largest size. 64 bit unsigned arithmetic requires special consideration.
I have one file created by c++ program which is in encrypted format. I want to read it in my java program. In case of decryption of file contents, decryption algorithm is performing operations on byte[which is unsigned char-BYTE in c/c++]. I used same decryption algorithm which I have used in my c/c++ program. This algorithm contains ^, %, * and - operations on byte. But byte datatype of java is signed because of which I am facing problems in decryption. How can I read file or process read data with 1byte at a time which is unsigned?
thanks in advance.
byte b = <as read from file>;
int i = b & 0xFF;
Perform operations on i as required
The standard method InputStream.read() reads one byte and fits it into a int, so in practice it is an unsinged byte. There are no unsigned primitive data types in java, so the only approach is to fit it in an upper primitive.
That being said you should have no trouble performing encryption/decryption over data bytes read from the file, since the bytes are the same, no matter if they are interpreted as signed or unsigned (0xFF can be 255 or -1). You say the alghorithm contains "^, %, *", etc. That is an interpretation of raw bytes, taking into account a character encoding (that fits 8 bit per character I suppose). You should not perform encryption/decryption operations over other than raw bytes.
First, InputStream.read() returns an int but it holds a byte; it uses an int so -1 can be returned if the EOF is reached. If the int is not -1, you can cast it to byte.
Second, there are read() metods that allow storing the bytes directly in a byte[]
And last, if you are going to use the file as a byte[] (and it is not too big) maybe it would be interesting copying the data from FileInputStream and write it into a ByteArrayOutputStream. You can get the resulting byte[] from the late object (note: do not use the .read() method, use .read(byte[], int, int) for performance).
Since there is no unsigned primitive type in Java, I think what you can do is to convert signed byte into integer (which will virtually be unsigned because the integer will always be positive). You can follow the code in here: Can we make unsigned byte in Java for the conversion.