since I need to control some devices, I need to send some bytes to them. I'm creating those bytes by putting some int values together (and operator), creating a byte and finally attaching it to a String to send it over the radio function to the robot.
Unfortuantely Java has some major issues doing that (unsigned int problem)
Does anybody know, how I can convert an integer e.g.
x = 223;
to an 8-bit character in Java to attach it to a String ?
char = (char)x; // does not work !! 16 bit !! I need 8 bit !
A char is 16-bit in Java. Use a byte if you need an 8-bit datatype.
See How to convert Strings to and from UTF8 byte arrays in Java on how to convert a byte[] to String with UTF-8 encoding.
Sending a java.lang.String over the wire is probably the wrong approach here, since Strings are always 16-bit (since Java was designed for globalization and stuff). If your radio library allows you to pass a byte[] instead of a String, that will allow you to send 8-bit values without needing to worry about converting to UTF8. As far as converting from an int to an unsigned byte, you'll probably want to look at this article.
int to array of bytes
public byte[] intToByteArray(int num){
byte[] intBytes = new byte[4];
intBytes[0] = (byte) (num >>> 24);
intBytes[1] = (byte) (num >>> 16);
intBytes[2] = (byte) (num >>> 8);
intBytes[3] = (byte) num;
return intBytes;
}
note endianness here is big endian.
Related
I know in java we can't deal with bit directly, I want to know how can we convert an byte array[] to byte. Such that
String bytestr="00000011";
byte[] noofbytes=bytestr.getBytes();
byte convbyte=(noofbytes[]) to byte
Is it possible ? does any one have any idea ?
Thanks.
I think you mean bits, not bytes.
String bitstr = "00000011";
byte convbyte = Byte.parseByte(bitstr, 2);
The , 2 tells it that you're parsing a binary (base 2) string; the default would be decimal (base 10).
based on this array :
final char[] charValue = { 'u', ' ', '}','+' };
i want to print the double value and the ascii value from it in Java.
i can't find a proper solution for that in internet. I just found how to convert a single Character into Integer value. But what about many characters?
the main problem is, i have a large char[] and some double and int values are stored in. for double values they are stored within 4 bytes size and integer 1 or 2 bytes so i have to read all this and convert into double or integer.
Thanks for you help
When java was designed, there was C char being used for binary bytes and text.
Java made a clear separation between binary data (byte[], InputStream/OutputStream) and Unicode text (char, String, Reader/Writer). Hence Java has full Unicode support. The binary data, byte[], need information: their used encoding, in order to be convertable to text: char[]/String.
In Java a char[] will rarely be used (as in C/C++), and it seems byte[] is intended, as you mention 4 elements to be used for an int etcetera. A char is 16 bits, containing UTF-16 text.
For this case one can use a ByteBuffer either wrapping a byte[] or being taken from a memory mapped file.
Writing
ByteBuffer buf = ByteBuffer.allocate(13); // 13 bytes
buf.order(ByteOrder.LITTLE_ENDIAN); // Intel order
buf.putInt(42); // at 0
buf.putDouble(Math.PI); // at 4
buf.put((byte) '0'); // at 12
buf.putDouble(4, 3.0); // at 4 overwrite PI
byte[] bytes = buf.array();
Reading
ByteBuffer buf = ByteBuffer.wrap(bytes);
buf.order(ByteOrder.LITTLE_ENDIAN); // Intel order
int a = buf.getInt();
double b = buf.getDouble();
byte c = buf.get();
This does not seem to be appropriate. Is there a way to create a hexadecimal array?
float[] bitBytes = {0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1};
for (int k = 0; k < alot; k++) {
BitSet.set(increment++, ((array[k] & (bitBytes[k%8]& 0xff)) != 0));
}
Hexadecimals is a representation of bytes as a String, or at least an array of characters. It is mainly used for human consumption, as it is easier to see the bit value of the bytes.
To create a byte array containing byte values, you can use the following construct:
final byte[] anArray = { (byte) 0x10, (byte) 0x80 };
The cast to byte - (byte) - is really only required for values of 0x80 or over as bytes are signed in Java and therefore only have values ranging from -0x80 to 0x7F. Normally we only deal with unsigned values though, so we need the cast.
Alternatively, for larger strings, it can be useful to simply supply a hexadecimal string to a decoder. Unfortunately the idiots that have thought out the standard API still haven't defined a standard hexadecimal codec somewhere in java.lang or java.util.
So you can use another library, such as the Apache codec library or a self written function. Stackoverflow to the rescue.
Convert a string representation of a hex dump to a byte array using Java?
If you want to have a BitSet of the values in the byte array, please use BitSet.valueOf(byte[])
byte[] biteBytes = new byte[8];
for (int j = 0; j < bitBytes.length; j++) {
bitBytes[j] = (byte) (Math.pow(2,j));
}
Hy guys!
I have the following problem:
I need to hash an unsigned byte in Java which is(would be...) between 0-255.
The main problem is that java doesnt have an unsigned Byte type at all.
I found a workaround for this, and used int instead of byte with a little modification.
The main problem is: Java.securitys Messagedigest.digest function only accepts byte array types, but i would need to give it an int array.
Anybody has a simpe workaround for this?
I was looking for a third party sha-1 function, but didnt found any. Nor any sample code.
So basically what i need:
I have an unsigned byte value for example: 0xFF and need to get the following sha1 hash: 85e53271e14006f0265921d02d4d736cdc580b0b
any help would be greatly appreciated.
It's important to understand that there is no difference between signed and unsigned bytes with respect to their representation. Signedness is about how bytes are treated by arithmetic operations (other than addition and subtraction, in the case of 2's complement representation).
So, if you use bytes for data storage, all you need is to make sure that you treat them as unsigned when converting values to bytes (use explicit cast with (byte), point 1) and from bytes (prevent sign extension with & 0xff, point 2):
public static void main(String[] args) throws Exception {
byte[] in = { (byte) 0xff }; // (1)
byte[] hash = MessageDigest.getInstance("SHA-1").digest(in);
System.out.println(toHexString(hash));
}
private static String toHexString(byte[] in) {
StringBuilder out = new StringBuilder(in.length * 2);
for (byte b: in)
out.append(String.format("%02X", b & 0xff)); // (2)
return out.toString();
}
Look at Apache Commons Codec library, method DigestUtils.sha(String data). It may be useful for you.
The digest won't care about how Java perceives the sign of a byte; it cares only about the bit pattern of the byte. Try this:
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update((byte) 0xFF);
byte[] result = digest.digest();
StringBuilder buffer = new StringBuilder();
for (byte each : result)
buffer.append(String.format("%02x", 0xFF & each));
System.out.println(buffer.toString());
This should print 85e53271e14006f0265921d02d4d736cdc580b0b.
I am accessing an ICU4C function through JNI which returns a UChar * (i.e. unicode character array).... I was able to convert that to jbyteArray by equating each member of the UChar array to a local jbyte[] array that I created and then I returned it to Java using the env->SetByteArrayRegion() function... now I have the Byte[] array in Java but it's all gibberish pretty much.. Weird symbols at best... I am not sure where the problem might be... I am working with unicode characters if that matters... how do I convert the byte[] to a char[] in java properly? Something is not being mapped right... Here is a snippet of the code:
--- JNI code (altered slighter to make it shorter) ---
static jint testFunction(JNIEnv* env, jclass c, jcharArray srcArray, jbyteArray destArray) {
jchar* src = env->GetCharArrayElements(srcArray, NULL);
int n = env->getArrayLength(srcArray);
UChar *testStr = new UChar[n];
jbyte destChr[n];
//calling ICU4C function here
icu_function (src, testStr); //takes source characters and returns UChar*
for (int i=0; i<n; i++)
destChr[i] = testStr[i]; //is this correct?
delete testStr;
env->SetByteArrayRegion(destArray, 0, n, destChr);
env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);
return (n); //anything for now
}
-- Java code --
string wohoo = "ABCD bal bla bla";
char[] myChars = wohoo.toCharArray();
byte[] myICUBytes = new byte[myChars.length];
int value = MyClass.testFunction (myChars, myICUBytes);
System.out.println(new String(myICUBytes)) ;// produces gibberish & weird symbols
I also tried: System.out.println(new String(myICUBytes, Charset.forName("UTF-16"))) and it's just as gebberishy....
note that the ICU function does return the proper unicode characters in the UChar *... somewheres between the conversion to jbyteArray and Java that is is messing up...
Help!
destChr[i] = testStr[i]; //is this correct?
This looks like an issue all right.
JNI types:
byte jbyte signed 8 bits
char jchar unsigned 16 bits
ICU4C types:
Define UChar to be wchar_t if that is
16 bits wide; always assumed to be
unsigned.
If wchar_t is not 16 bits wide, then
define UChar to be uint16_t or
char16_t because GCC >=4.4 can handle
UTF16 string literals. This makes the
definition of UChar platform-dependent
but allows direct string type
compatibility with platforms with
16-bit wchar_t types.
So, aside from anything icu_function might be doing, you are trying to fit a 16-bit value into an 8-bit-wide type.
If you must use a Java byte array, I suggest converting to the 8-bit char type by transcoding to a Unicode encoding.
To paraphrase some C code:
UChar *utf16 = (UChar*) malloc(len16 * sizeof(UChar));
//TODO: fill data
// convert to UTF-8
UConverter *encoding = ucnv_open("UTF-8", &status);
int len8 = ucnv_fromUChars(encoding, NULL, 0, utf16, len16, &status);
char *utf8 = (char*) malloc(len8 * sizeof(char));
ucnv_fromUChars(encoding, utf8, len8, utf16, len16, &status);
ucnv_close(encoding);
//TODO: char to jbyte
You can then transcode this to a Java String using new String(myICUBytes, "UTF-8").
I used UTF-8 because it was already in my sample code and you don't have to worry about endianness. Convert my C to C++ as appropriate.
Have you considered using ICU4J?
Also, when converting your bytes to a string, you will need to specify a character encoding. I'm not familiar with the library in question, so I can't advise you further, but perhaps this will be "UTF-16" or similar?
Oh, and it's also worth noting that you might simply be getting display errors because the terminal you're printing to isn't using the correct character set and/or doesn't have the right glyphs available.