Transform String value to bytearray java - java

I have a string which contains the byte array's String value for example like this [B#42031498
I want to retrieve the String content as byte[] ? How can I do that ?
PS : converting the string with String.getBytes() method doesn't work . It converts the string but doesn't give me the value as byte array. It works like this.
If It's is not possible is there a way to get byte[] from Object in java (and always without converting)

converting the string with String.getBytes() method doesn't work . It converts the string but doesn't give me the value as byte array.
Yes it does.
You have two problems:
you try and print the array directly; you should use Arrays.toString(), otherwise the .toString() method of the array itself is called;
you don't specify the encoding; you should really use .getBytes(StandardCharsets.UTF_8) to have the same result on all environments.
In the same manner, building a string from a byte array should be done using the correct encoding: new String(array, StandardCharsets.UTF_8).

if [B#42031498 has already been saved into a String, there is no way you can get this back to the originating byte array. Look at the following example:
String str = "[B#42031498";
byte[] ba = str.getBytes();
String s = new String(ba);
System.out.println(s);
This will output [B#42031498

What you have done:
byte[] array = ....
String result = array.toString();
What you (probably) want:
String result = new String(array, "UTF-8");

Iterate the byte array as below and you will get the byte value :
for (byte b : bytes) {
System.out.println(b);
}
The output B#42031498 you get because of Object class toString() method .
public String toString()
{
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}

Related

Java - checking encoding of string for unit test?

I have a unit test I was trying to write for a generateKey(int **length**) method. The method:
1. Creates a byte array with size of input parameter length
2. Uses SecureRandom().nextBytes(randomKey) method to populate the byte array with random values
3. Encodes the byte array filled with random values to a UTF-8 String object
4. Re-writes the original byte array (called randomKey) to 0's for security
5. Returns the UTF-8 encoded String
I already have a unit test checking for the user inputting a negative value (i.e. -1) such that the byte array would throw a Negative array size exception.
Would a good positive test case be to check that a UTF-8 encoded String is successfully created? Is there a method I can call on the generated String to check that it equals "UTF-8" encoding?
I can't check that the String equals the same String, since the byte array is filled with random values each time it is called....
source code is here:
public static String generateKey(int length) {
byte[] randomKey = new byte[length];
new SecureRandom().nextBytes(randomKey);
String key = new String(randomKey, Charset.forName("UTF-8"));//Base64.getEncoder().encodeToString(randomKey);
Arrays.fill(randomKey,(byte) 0);
return key;
}
You can convert a UTF8 string to a byte array as below
String str = "私の"; // replace this with your generateKey result
byte [] b = str.getBytes();
String newString;
try {
newString = new String (b, "UTF-8");
System.out.println(newString);
System.out.println("size is equal ? " + (str.length() == newString.length()));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
First, the code you posted is simply wrong: you can't take a random array of bytes and treat it as a UTF-8 string, because UTF-8 expects certain bit patterns to indicate multi-byte characters.
Unfortunately, this failure happens silently, because you're using a string constructor that "always replaces malformed-input and unmappable-character sequences with this charset's default replacement string". So you'll get something, but you wouldn't be able to translate it back to the same binary value.
The comment in the code, however, gives you the answer: you need to use Base64 to encode the binary value.
However, that still won't let you verify that the encoded string is equivalent to the original byte array, because the function takes great care to zero out the array immediately after use (which doesn't really do what the author thinks it does, but I'm not going to get into that argument).
If you really want to test a method like this, you need to be able to mock out core parts of it. You could, for example, separate out the generation of random bytes from encoding, and then pass in a byte generator that keeps track of the bytes that it generated.
But the real question is why? What are you (or more correctly, the person writing this code) actually trying to accomplish? And why won't a UUID accomplish it?

byte[] toString() gives a weird string instead of actual value

byte[] a has value of {119}, which is the ascii equivalent of "w", but when I use .toString() to convert it to string, it gives me a weird string. any idea what I did wrong?
byte[] a = characteristicRX.getValue();
String rscvString = a.toString();
Log.d("byteToHex", "rscvString = " + rscvString);
while ( rscvString != "w" ){
String object takes a parameter of byte[] as an overloaded constructor. Use String rscvString = new String(a); and you should be sorted
You can't use boolean operators to test against strings ie. != or ==.
use while ( !(rscvString.equalsIgnoreCase("w") ) the equalsIgnoreCase() method will return a boolean and the ! will force the test against the false.
Try one of the lines below to cast a byte to a character and transform it to String
String rscvString = String.valueOf((char) a);
String rscvString = String.valueOf((char) (a & 0xFF));
You can pass a byte array in the String constructor to get a String object of your array.

ASCII to HEX string in Java returns ASCII value and not HEX

I am trying to convert an ASCII string into HEX. But for some reason, it is giving me back the ASCII value instead of the HEX value.
So here is my code:
public String toHex(String strToConvert) {
ByteBuffer bb = ByteBuffer.wrap(strToConvert.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
while (bb.hasRemaining()) {
sb.append(bb.get());
}
return sb.toString();
}
The function call is made like: toHex("A");. What am I doing wrong?
Try using:
System.out.println(String.format("%02X", char_value))
There is nothing in your code that converts the byte you are getting from the buffer to hexadecimal; the sb.append(int) method that you are calling converts it to decimal, not hexadecimal. One solution is to do this:
sb.append(String.format("%02X", bb.get()));
Note that you call your method "ASCII to hex", but you are not actually using ASCII - you are using UTF-8, which is not exactly the same as ASCII.

Apache common codec in java from string to hex and viceversa

I am trying to encode a string in hex and then convert it again to string. For this purpose I'm using the apache common codec. In particular I have defined the following methods:
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
public String toHex(byte[] byteArray){
return Hex.encodeHexString(byteArray);
}
public byte[] fromHex(String hexString){
byte[] array = null;
try {
array = Hex.decodeHex(hexString.toCharArray());
} catch (DecoderException ex) {
Logger.getLogger(SecureHash.class.getName()).log(Level.SEVERE, null, ex);
}
return array;
}
The strange thing is that I do not get the same initial string when converting back. More strangely, the byte array I get, it's different from the initial byte array of the string.
The small test program that I wrote is the following:
String uno = "uno";
byte[] uno_bytes = uno.getBytes();
System.out.println(uno);
System.out.println(uno_bytes);
toHex(uno_bytes);
System.out.println(hexed);
byte [] arr = fromHex(hexed);
System.out.println(arr.toString());
An example of output is the following:
uno #initial string
[B#1afe17b #byte array of the initial string
756e6f #string representation of the hex
[B#34d46a #byte array of the recovered string
There is also another strange behaviour. The byte array ([B#1afe17b) is not fixed, but is different from run to run of the code, but I cannot understand why.
When you print a byte array, the toString() representation does not contain the contents of the array. Instead, it contains a type indicator ([B means byte array) and the hashcode. The hashcode will be different for two distinct byte arrays, even if they contain the same contents. See Object.toString() and Object.hashCode() for further information.
Instead, you maybe want to compare the arrays for equality, using:
System.out.println("Arrays equal: " + Arrays.equals(uno_bytes, arr));

Converting a string to byte[] such that the contents remain same

I have a String say String a = "abc";. Now I want to convert it into a byte array say byte b[];, so that when I print b it should show "abc".
How can I do that?
getBytes() method is giving different result.
My program looks like that so far:
String a="abc";
byte b[]=a.getBytes();
what I want is I have two methods made in a class one is
public byte[] encrypt(String a)
and another is
public String decrypt(byte[] b)
after doing encryption i saved the data into database but when i am getting it back then byte methods are not giving the correct output but i got the same data using String method but now I have to pass it into decrypt(byte[] b)
How to do it this is the real scenario.
Well, your first problem is that a String in Java is not an array of bytes, but of chars, where each of them takes 16bit. This is to cover for unicode characters, instead of only ascii that you'd get with bytes. That means that if you use the getBytes method, you won't be able to print the string one array position at a time, since it takes two array positions (two bytes) to represent one character.
What you could do is use getChars and then cast each char to a byte, with the corresponding precision los. This is not a good idea since it won't work outside of normal English characters! You asked, though, so here you go ;)
EDIT: as #PeterLawerey mentions,Unicode characters make it even harder, with some unicode characters needing more than one char. There's a good discussion in StackOverflow and it links to an detailed article from Oracle.
byte b[]=a.getBytes();
System.out.println(new String(b));
You could use this constructor to build your string back again:
String a="abc";
byte b[]=a.getBytes("UTF-8");
System.out.println(new String(b, "UTF-8"));
Other than that, you can't do System.out.println(b) and expect to see abc.
A byte is value between -128 and 127. When you print it, it will be a number by default.
If you want to print it as an ASCII char, you can cast it to a (char)
byte[] bytes = "abc".getBytes();
for(byte b: bytes)
System.out.println((char) b);
prints
a
b
c
It seems like you are implementing encryption and decryption code.
String constructors are for text data. you should not use it to convert byte array
which contains encrypted data to string value.
You should use base64 instead, which encodes any binary data into ASCII.
this one is good public domain one
http://iharder.sourceforge.net/current/java/base64/
base64 apache commons
http://commons.apache.org/codec/download_codec.cgi
String msg ="abc";
byte[] data = Base64.decode(msg);
String convert = Base64.encodeBytes(data);
This will convert "abc" to byte and then the code will print "abc" in respective ASCII code (ie. 97 98 99).
byte a[]=new byte[160];
String s="abc";
a=s.getBytes();
for(int i=0;i<s.length();i++)
{
System.out.print(a[i]+" ");
}
If you add these lines it will again change the ASCII code to String (ie. abc)
String s1=new String(a);
System.out.print("\n"+s1);
Hope it Helpes.
Modified Code:
To send byte array as an argument:
public static void another_method_name(byte b1[])
{
String s1=new String(b1);
System.out.print("\n"+s1);
}
public static void main(String[] args)
{
byte a[]=new byte[160];
String s="abc";
a=s.getBytes();
for(int i=0;i<s.length();i++)
{
System.out.print(a[i]+" ");
}
another_method_name(a);
}
Hope it helps again.

Categories

Resources