Parse byte[] from String initializer "new byte[]{1,2,3}" - java

Hi Team,Firstly I don't want a byte[] array made from the actual String/char[]
//NO!
String s = "abc";
byte[] bytes = s.getBytes();
I want a byte[] array constructed by the contents and representation of the String, like so.
byte[] b = "new byte[]{1,2,3}"
//Again I don't want >> byte[] b = new String("new byte[]{1,2,3}").getBytes();
thanks Team.

This worked for me -
/**
* Parse a properly formatted String into a byte array.
*
* #param in
* The string to parse - must be formatted
* "new byte[]{1,2,n}"
* #return The byte array parsed from the input string.
*/
public static byte[] parseByteArrayFromString(
String in) {
in = (in != null) ? in.trim() : "";
// Opening stanza.
if (in.startsWith("new byte[]{")) {
// Correct closing brace?
if (in.endsWith("}")) {
// substring the input.
in = in.substring(11, in.length() - 1);
// Create a list of Byte(s).
List<Byte> al = new ArrayList<Byte>();
// Tokenize the input.
StringTokenizer st = new StringTokenizer(in,
",");
while (st.hasMoreTokens()) {
String token = st.nextToken();
// Add a Byte.
al.add(Byte.valueOf(token.trim()));
}
// Convert from the List to an Array.
byte[] ret = new byte[al.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = al.get(i);
}
return ret;
}
}
return new byte[] {};
}
public static void main(String[] args) {
byte[] vals = parseByteArrayFromString("new byte[]{1,2,3}");
System.out.println(Arrays.toString(vals));
}

Well, you could always just traverse through the array and put those values in a string, then put those in a byte array.
String d = "new byte[]{";
for(int i = 0; i < s.length() - 1; i++)
d += s.charAt(i) +",";
d += s.charAt(s.length() - 1) + "}";
byte[] b = d.getBytes();

You can extract bytes by using regular expression, such as:
Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
Byte.parseByte(matcher.group(0)).byteValue(); // Use this
}
In the while loop, use can add them to an array to use it later or print it to console, or any else. It's up to you.
For sure that input string is correct, add another pattern to check that string if necessary. For example:
Pattern.compile("new byte\\[\\] ?\\{((\\d+),? *)+\\}");

Related

How to convert hexstring to ANSI (window 1252) and convert ANSI (window 1252) back to hex string in Java?

How to convert hex string to ansi (window 1252) and ansi (window 1252)to hex string in Java.
python (Works perfectly)
q = "hex string value"
x = bytes.fromhex(q).decode('ANSI')
a = x.encode("ANSI")
a = a.hex()
if q==a:
print("Correct")
Java (This code has a problem)
String hexOri = "hex string value";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hexOri.length(); i+=2) {
String str = hexOri.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println("ANSI = " + output);
char [] chars = output.toString().toCharArray();
StringBuffer hexOutput = new StringBuffer();
for(int i = 0; i < chars.length; i++){
hexOutput.append(Integer.toHexString((int)chars[i]));
}
System.out.println("HexOutput = " + hexOutput.toString());
System.out.println(hexOri.equals(hexOutput.toString()));
Output from Python
Correct
Expected Output from Python
Correct
Output from Java
False
Expected Output from Java
Correct
In java the strings are encoded in UTF-16, so you can't read simply read/write the bytes of a string to get the encoding representation you desire.
You should use String#getBytes(String str, String charset) to get the string converted in the encoding you need and serialized to a byte array.
The same thing must be done to decode a byte array, using new String(buffer,encoding).
In both cases if you use the method without the charset it will use the default encoding for the JVM instance (which should be the system charset).
public static void main(String[] args) {
String str = "\tSome text [à]";
try {
System.out.println(str); // Some text [à]
String windowsLatin1 = "Cp1252";
String hexString = toHex(windowsLatin1, str);
System.out.println(hexString); // 09536f6d652074657874205be05d
String winString = toString(windowsLatin1, hexString);
System.out.println(winString); // Some text [à]
} catch (UnsupportedEncodingException e) {
// Should not happen.
}
}
public static String toString(String encoding, String hexString) throws UnsupportedEncodingException {
int length = hexString.length();
byte [] buffer = new byte[length/2];
for (int i = 0; i < length ; i+=2) {
String hexVal = hexString.substring(i,i+2);
byte code = (byte) Integer.parseInt(hexVal,16);
buffer[i/2]=code;
}
String winString = new String(buffer,encoding);
return winString;
}
public static String toHex(String encoding, String str) throws UnsupportedEncodingException {
byte[] bytes = str.getBytes(encoding);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
String hexChar = Integer.toHexString(b & 0xff);
if(hexChar.length()<2) {
builder.append('0');
}
builder.append(hexChar);
}
String hexString = builder.toString(); // 09536f6d652074657874205be05d
return hexString;
}

How can i revert back hexa value of certain language word to UTF-8

I have converted regional language word to hex value and saved to DB. But How can i decode that hexa value back to regional language word.
Here is my Kannada/Telugu word to Hex value conversion
public String toHex(String b){
String s="";
for (int i=0; i<b.length(); ++i) s+=String.format("%04X",b.charAt(i)&0xffff);
System.out.println("Converted value:::"+s); //0C1C0C3E0C350C3E
return s;
}
Word i have saved is జావా
Hex value saved in database is 0C1C0C3E0C350C3E
Decoded output am getting is : >5>
Is there any way to decode the hex value back to జావా
Code used to decode is
byte[] bytes = DatatypeConverter.parseHexBinary(itemName);
String s= new String(bytes, "UTF-8");
System.out.println("Utf..."+s);
Please help...
public String fromHex(String b) {
char[] cs = new char[b.length() / 4];
for (int i = 0; i < cs.length; ++i) {
int c = Integer.parseInt(b.substring(4 * i, 4 * i + 4), 16) & 0xFFFF;
cs[i] = (char) c;
}
return new String(cs);
}
This assumes that the conversion did not meddle with negative hex values.
Or exploiting that char is UTF-16BE:
byte[] bytes = DatatypeConverter.parseHexBinary(itemName);
return new String(bytes, StandardCharsets.UTF_16);
char[] data = hexData.toCharArray();
byte[] bytes = new byte[data.length/2];
for (int i = 0; i < data.length; i += 2) {
String val = new String(data, i, 2);
bytes[i/2] = Integer.valueOf(val, 16).byteValue();
}
String text = new String(bytes, "UTF8");
You might add sanity checks, e.g. that the length of the input-array is even, etc.

how to preserve newline character in a string after converting to bytes?

String str[] = {"1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||1||7707||0||"
+ "0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441^^1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||"
+ "1||7707||0||0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441","1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||1||7707||0||"
+ "0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441^^1000458551||A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F||"
+ "1||7707||0||0||1002||1373569142000||HTC One||val||4.1.2||0||1.01.20130206.15441"};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(String p:str){
String Recordstore[] = p.split("\\^\\^");
long len = Recordstore.length;
long counter = 0;
StringBuffer finalRecord = new StringBuffer();
for (String rec : Recordstore) {
rec = rec.replaceAll("\\|\\|", "|");
if (counter != len - 1)
finalRecord.append(rec).append(System.lineSeparator());
else
finalRecord.append(rec);
counter++;
}
baos.write(finalRecord.toString().getBytes());
}
ByteArrayInputStream object = new ByteArrayInputStream(
baos.toByteArray());
String pr="";
for(int y = 0 ; y < 1; y++ ) {
while(( c= object.read())!= -1) {
pr+=(char)c;
}
System.out.println(pr);
object.reset();
}
After converting the string to bytes and rechecking the bytes, I see that the new line character is lost and the string are combined in a single line.
How to be able to preserve the new line character even after the conversion to bytes?
Sample Output is :
adding the new line to the string and printing the string gives:
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
After converting it to bytes and printing the string
1000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.154411000458551|A210171046D86F9F6EE21B66FE9B1441E20EC1DEF9654A2D092162591C01D26F|1|7707|0|0|1002|1373569142000|HTC One|val|4.1.2|0|1.01.20130206.15441
Thanks for the reply in advance
Because this line is never executed.
finalRecord.append(rec).append(System.lineSeparator());
I'm not sure why you split string like this:
String Recordstore[] = p.split("\\^\\^");
Obviously, the array Recordstore.length() will always be 1, since there isn't any ^^ in your original string.
So counter != len - 1 will always be false.
update:
I made some changes in this line:
baos.write(finalRecord.append(System.lineSeparator()).toString().getBytes());

Hex to ASCII showing different result to correct PHP implementaiton

I needed a method that would convert hex to ascii, and most seem to be a variation of the following:
public String hexToAscii(String hex) {
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
for(int i = 0; i < hex.length() - 1; i += 2){
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
sb.append((char)decimal);
temp.append(decimal);
}
return sb.toString();
}
The idea is to look at
hexToAscii("51d37bdd871c9e1f4d5541be67a6ab625e32028744d7d4609d0c37747b40cd2d");
If I print the result out, I get
-Í#{t7?`Ô×D?2^b«¦g¾AUM??Ý{ÓQ.
This is not the result I am needing though. A friend got the correct result in PHP which was the string reverse of the following:
QÓ{݇žMUA¾g¦«b^2‡D×Ô`7t{#Í-
There are clearly characters that his hexToAscii function is encoding whereas mine is not.
Not really sure why this is the case, but how can I implement this version in Java?
Assuming your input string is in, I would use a method like this
public static byte[] decode(String in) {
if (in != null) {
in = in.trim();
List<Byte> bytes = new ArrayList<Byte>();
char[] chArr = in.toCharArray();
int t = 0;
while (t + 1 < chArr.length) {
String token = "" + chArr[t] + chArr[t + 1];
// This subtracts 128 from the byte value.
int b = Byte.MIN_VALUE
+ Integer.valueOf(token, 16);
bytes.add((byte) b);
t += 2;
}
byte[] out = new byte[bytes.size()];
for (int i = 0; i < bytes.size(); ++i) {
out[i] = bytes.get(i);
}
return out;
}
return new byte[] {};
}
And then you could use it like this
new String(decode("51d37bdd871c9e1f4d5541be67a6ab625e"
+"32028744d7d4609d0c37747b40cd2d"))
How about trying like this:
public static void main(String[] args) {
String hex = "51d37bdd871c9e1f4d5541be67a6ab625e32028744d7d4609d0c37747b40cd2d";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
String str = hex.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println(output);
}

Hex-encoded String to Byte Array

String str = "9B7D2C34A366BF890C730641E6CECF6F";
I want to convert str into byte array, but str.getBytes() returns 32 bytes instead of 16.
I think what the questioner is after is converting the string representation of a hexadecimal value to a byte array representing that hexadecimal value.
The apache commons-codec has a class for that, Hex.
String s = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = Hex.decodeHex(s.toCharArray());
Java SE 6 or Java EE 5 provides a method to do this now so there is no need for extra libraries.
The method is DatatypeConverter.parseHexBinary
In this case it can be used as follows:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
byte[] bytes = DatatypeConverter.parseHexBinary(str);
The class also provides type conversions for many other formats that are generally used in XML.
Use:
str.getBytes("UTF-16LE");
I know it's late but hope it will help someone else...
This is my code: It takes two by two hex representations contained in String and add those into byte array.
It works perfectly for me.
public byte[] stringToByteArray (String s) {
byte[] byteArray = new byte[s.length()/2];
String[] strBytes = new String[s.length()/2];
int k = 0;
for (int i = 0; i < s.length(); i=i+2) {
int j = i+2;
strBytes[k] = s.substring(i,j);
byteArray[k] = (byte)Integer.parseInt(strBytes[k], 16);
k++;
}
return byteArray;
}
That should do the trick :
byte[] bytes = toByteArray(Str.toCharArray());
public static byte[] toByteArray(char[] array) {
return toByteArray(array, Charset.defaultCharset());
}
public static byte[] toByteArray(char[] array, Charset charset) {
CharBuffer cbuf = CharBuffer.wrap(array);
ByteBuffer bbuf = charset.encode(cbuf);
return bbuf.array();
}
try this:
String str = "9B7D2C34A366BF890C730641E6CECF6F";
String[] temp = str.split(",");
bytesArray = new byte[temp.length];
int index = 0;
for (String item: temp) {
bytesArray[index] = Byte.parseByte(item);
index++;
}
I assume what you need is to convert a hex string into a byte array that equals that means the same thing as that hex string?
Adding this method should do it for you, without any extra library importing:
public static byte[] hexToByteArray(String s) {
String[] strBytes = s.split("(?<=\\G.{2})");
byte[] bytes = new byte[strBytes.length];
for(int i = 0; i < strBytes.length; i++)
bytes[i] = (byte)Integer.parseInt(strBytes[i], 16);
return bytes;
}

Categories

Resources