Java String to array of bytes wrong conversion - java

I have a client server Java code and the client is reading in a string "input" and it should then decrypt it, the decryption function needs an array of bytes, so I need to convert the string to array of bytes, which is done using "getBytes()" function, however it seems that this function is modifying the String! How can I convert the string into an array of bytes without changing its content.
String input = inputline.substring(66, inputline.length());
System.out.println("Read message +"+input+"+");
byte[] bx = input.getBytes(Charset.forName("UTF-8"));
System.out.println("Read message +"+bx.toString()+"+");
System.out.println("Read message +"+bx+"+");
the output of the code snippet is as follows:
Read message +[B#161cd475+
Read message +[B#4e25154f+
Read message +[B#4e25154f+

Try writing a for loop to print out the results. I believe Java is spitting out a random memory value for your output.
(int i = 0; s <= bx.length;i++)
{
System.out.println("Read message +" + bx[i].toString() + "+");
System.out.println("Read message +" + bx + "+");
}
Not sure if my for loop is correct, but it may give you something to work with. I hope this helps.

This should work for you. I needed to make a String object from the byte array...
String inputline = "[B#161cd475";
String input = inputline.substring(0, inputline.length());
System.out.println("Read message +"+input+"+");
byte[] bx = input.getBytes();
// Convert to String object
String tmp = new String(bx);
// Print statements.
System.out.println("Read message +" + tmp + "+");

Related

How to read data coming from TCP Socket separated by a specific delimeter

I need to read Bytes of data from a Server using Socket connection over TCP. The data is in the form of a Byte Stream delimited by delimited by one or more octets with a value of 255 (0xFF)
I am using BufferedInputSream to read the data. A part of my code is below:
String messageString = "";
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] bytes = new byte[16 * 1024];
System.out.println("Receiving Bytes");
while(true)
{
bytesRead = in.read(bytes);
messageString += new String(bytes,0,bytesRead);
if (<SOME CONDITION TO KNOW THAT DELIMITER IS RECEIVED>)
{
System.out.println("Message Received: " + messageString);
//Proceed to work with the message
messageString = "";
}
}
I need the IF condition so that I know that I have received one data packet and start processing the same.
I don't know the length of the message that I am going to receive neither I have the information to the length in the incoming message.
Please help me read this type of byte data.
Any help is truly appreciated.
If your delimiter is 255 you can just check the data you just read for that value:
bytesRead = in.read(bytes);
int index= bytes.indexOf(255);
if (index<0)
{
messageString += new String(bytes,0,bytesRead);
}
else //<SOME CONDITION TO KNOW THAT DELIMITER IS RECEIVED>)
{
messageString += new String(bytes,0,index);
System.out.println("Message Received: " + messageString);
//Proceed to work with the message
messageString = "";
}

ObjectOutputStream.writeBytes(String s) unexpected output values

I am using an ObjectOutputStream object os to send a String msg from a client Android app to a c++ server.
I know how my msg must be received by the server:
each char of the msg is stored in a byte array (received_msg[]). I also know the exact msg the server expects (through another c++ app).
The data I send is a string made from 1 byte array and 2 other string.
My problem:
I already used PrintWriter to send my data, but my server would always display some weird char in received_msg, at index 24 to 28.
I tried a lot of conversions to fix it, but gave up on that.
So I tried sending msg with ObjectOutputStream.
With the client using ObjectOutputStream.writeBytes(), the server shows almost the right received message. Almost because there are characters that are added at the beginning.
Something like that :
In the server received_msg:
index 0: ┐
index 1: i
index 2: ''
index 3: |
index 4: I //beginning of the message I actually wanted to send
index 5: S //every char following index 4 is good.
while I expected and sent nothing before 'I''S'.
The message I send begins like that : ISOXXXXX
So I was wondering if there were any ways to retrieve the REAL output of ObjectOutputStream.writeBytes. I know that it's Output, not Input, still that would help me understand how it adds the weird header.
Thanks in advance for your suggestion
My send function
private void send(String o) {
System.out.println("socket");
try {
this.socket = new Socket(serverIP, portNumber);
os = new ObjectOutputStream(socket.getOutputStream());
//OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
//InputStreamReader in = new InputStreamReader(socket.getInputStream());
// PrintWriter pw = new PrintWriter(out, true);
System.out.println("Connected to server : " + this.socket.getInetAddress() + " on port " + this.socket.getPort());
System.out.println("from local address: " + this.socket.getLocalAddress() + " and port: " + this.socket.getLocalPort());
System.out.println("02. -> Sending an object...");
ArrayList<String> tempoStr = StringToByteArray(o);
String msg="";
for(String inStr :tempoStr)
msg+=inStr;
System.out.println("the message I ACTUALLY send is\n"+msg); //the result in console is EXACTLY the message I expect.
os.writeBytes(msg); //then when I check on the server: unexpected additionnal chars at the beginning.
os.flush();
// pw.write(msg);
//pw.flush();
System.out.println("send success");
} catch (IOException e) {
e.printStackTrace();
System.out.println("XX. Exception Occurred on Sending:" + e.toString() +"\n"+ e.getCause());
System.out.println("Socket creation failure or error on sending.");
}
}
PS: I cannot change the server code.
Do not use ObjectOutputStream (java only). One might use DataOutputStream, but here it seems you want something simple.
byte[] a = ...
String b = ...
OutputStream out = ...
out.write(a);
out.write((b + '\u0000').getBytes("UTF-8")); // Or "Windows-1252" / "ISO-8859-1"
out.flush();
I have added a '\0' as that is used in C/C++ to terminate strings (binary output).
Or maybe "\r\n" might be expected (text output).
The encoding is given explicitly.

Received UDP message has incorrect length

I am recieving a UDP message from a DatagramSocket and am trying to parse the message like this:
this.broadSock.receive(recvPacket);
// Decode response
byte[] response = recvPacket.getData();
String strResp = new String(response);
String[] splitResp = strResp.split("\\s+");
log.debug("The String: " + strResp + " has the length " + strResp.length());
InetAddress lobbyAdress = InetAddress.getByName(splitResp[0].substring(1));
String portStr = splitResp[1];
int lobbyPort = Integer.parseInt(portStr);
I am getting the following Exception:
java.lang.NumberFormatException: For input string: "8080"
So there is something wrong with the received String as the debug output gives me:
The String: /192.168.0.11 8080 has the length 256
Anybody an idea why this is happening?
The length is provided, and you're ignoring it. It should be:
String strResp = new String(packet.getData(), packet.getOffset(), packet.getLength());
String[] splitResp = strResp.split("\\s+");
log.debug("The response: " + strResp + " has the length " + packet.length());
The fact that strResp.length is 256 is a symptom of a bug in your code. It should be 18 instead.
You are constructing strResp using the entire length of the DatagramPacket buffer without regard to how many bytes are actually in that buffer. DatagramPacket.getData() does not return a new byte[] for just the bytes received. It returns the entire buffer.
That means strResp ends up with 238 extra characters after the port number, and they are not whitespace characters that would be stripped off by split("\\s+"), so splitResp[1], and thus strPort, ends up with more than just digit characters in it, thus violating the requirements of Integer.parseInt().
You need to take the DatagramPacket length into account when constructing strResp:
byte[] response = recvPacket.getData();
int responseOffset = recvPacket.getOffset();
int responseLength = recvPacket.getLength();
String strResp = new String(response, responseOffset, responseLength);

receiving a C struct from serial port using Java

I've got two programs. one is written in C, sending out structs of unsinged chars via serial port.
The other one is written in Java and supposed to receive this data.
I'm using the jSSC library which returns a byte array after reading from the serial port.
How can I now extract the original values?
what is send: 1,99,23,15,16,17,18
bytes I received: [B#c1c428
bytes converted to chars: [C#13526b0
Sending the data works correctly. I also wrote a C program to read the data which receives it correctly so the problem seems to be in the Java program.
System.out.println("Port " + PortName + " opened: " + serialPort.openPort());
//serialPort.setParams(9600, 8, 1, 0);
byte[] input;
if((input = serialPort.readBytes()) == null){
System.out.println("No data to be read");
System.exit(0);
}
char[] chars = new String(input).toCharArray();
System.out.println("Bytes read: " + input.length);
System.out.println("Byteoutput: " + input);
System.out.println("Charoutput: " + chars);
In order to actually output a byte array you need to do something like:
System.out.print("Byte output: ");
for(int i=0; i < input.length; ++i)
System.out.print(((int)input[i]) + ", ");
System.out.println();

Check if a String is valid UTF-8 encoded in Java

How can I check if a string is in valid UTF-8 format?
Only byte data can be checked. If you constructed a String then its already in UTF-16 internally.
Also only byte arrays can be UTF-8 encoded.
Here is a common case of UTF-8 conversions.
String myString = "\u0048\u0065\u006C\u006C\u006F World";
System.out.println(myString);
byte[] myBytes = null;
try
{
myBytes = myString.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
System.exit(-1);
}
for (int i=0; i < myBytes.length; i++) {
System.out.println(myBytes[i]);
}
If you don't know the encoding of your byte array, juniversalchardet is a library to help you detect it.
The following post is taken from the official Java tutorials available at: https://docs.oracle.com/javase/tutorial/i18n/text/string.html.
The StringConverter program starts by creating a String containing
Unicode characters:
String original = new String("A" + "\u00ea" + "\u00f1" + "\u00fc" + "C");
When printed, the String named original appears as:
AêñüC
To convert the String object to UTF-8, invoke the getBytes method and
specify the appropriate encoding identifier as a parameter. The
getBytes method returns an array of bytes in UTF-8 format. To create a
String object from an array of non-Unicode bytes, invoke the String
constructor with the encoding parameter. The code that makes these
calls is enclosed in a try block, in case the specified encoding is
unsupported:
try {
byte[] utf8Bytes = original.getBytes("UTF8");
byte[] defaultBytes = original.getBytes();
String roundTrip = new String(utf8Bytes, "UTF8");
System.out.println("roundTrip = " + roundTrip);
System.out.println();
printBytes(utf8Bytes, "utf8Bytes");
System.out.println();
printBytes(defaultBytes, "defaultBytes");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
The StringConverter program prints out the values in the utf8Bytes and
defaultBytes arrays to demonstrate an important point: The length of
the converted text might not be the same as the length of the source
text. Some Unicode characters translate into single bytes, others into
pairs or triplets of bytes.
The printBytes method displays the byte arrays by invoking the byteToHex method, which is defined in the source file,
UnicodeFormatter.java. Here is the printBytes method:
public static void printBytes(byte[] array, String name) {
for (int k = 0; k < array.length; k++) {
System.out.println(name + "[" + k + "] = " + "0x" +
UnicodeFormatter.byteToHex(array[k]));
}
}
The output of the printBytes method follows. Note that only the first
and last bytes, the A and C characters, are the same in both arrays:
utf8Bytes[0] = 0x41
utf8Bytes[1] = 0xc3
utf8Bytes[2] = 0xaa
utf8Bytes[3] = 0xc3
utf8Bytes[4] = 0xb1
utf8Bytes[5] = 0xc3
utf8Bytes[6] = 0xbc
utf8Bytes[7] = 0x43
defaultBytes[0] = 0x41
defaultBytes[1] = 0xea
defaultBytes[2] = 0xf1
defaultBytes[3] = 0xfc
defaultBytes[4] = 0x43

Categories

Resources