I'm trying to convert a 32-byte string of hex characters (b8aa30d8f1d398883f0eeb5079777c42) into a 16-byte string of hex values (x'b8aa30d8f1d398883f0eeb5079777c42')
I've tried some of the suggestions I've found here.
StringBuffer sb = new StringBuffer();
for (int i = 0; i < input.length(); i++) {
String s = input.substring(i, i + 2);
byte value = Byte.valueOf(s, 16);
sb.append(value);
}
this resulted in this Exception: Value out of range. Value:"b8" Radix:16
String bin = "";
String binFragment = "";
int iHex;
hex = hex.trim();
hex = hex.replaceFirst("0x", "");
for(int i = 0; i < hex.length(); i++){
iHex = Integer.parseInt(""+hex.charAt(i),16);
binFragment = Integer.toBinaryString(iHex);
while(binFragment.length() < 4){
binFragment = "0" + binFragment;
}
bin += binFragment;
}
this doesn't handle leading 0's correctly
does anyone have a way to do this conversion?
I also tried this:
public static void convert() {
String s = "0c871eea3af7526f9b2e7054f6277984";
byte[] bytes = DatatypeConverter.parseHexBinary(s);
StringBuilder outputStringBuilder = new StringBuilder();
for (byte currentByte : bytes) {
outputStringBuilder.append((char) currentByte);
}
System.out.println(String.format("%s, %s", bytes, bytes.length));
String out = bytes.toString();
System.out.println(String.format("%s, %s", out, out.length()));
}
and got these results:
[B#f01a1e, 16
[B#f01a1e, 9
There are 16 bytes in the byte array before creating the output string, but only 9 after.
If I understand you correctly, you are trying to convert a sequence of bytes (given in hexadecimal notation as a String) to the corresponding characters.
You can use the DatatypeConverter class to convert the hex-string into an array of bytes ...
byte[] bytes = DatatypeConverter.parseHexBinary(inputString);
... and convert each byte to the character it represents:
StringBuilder outputStringBuilder = new StringBuilder();
for (byte currentByte : bytes) {
outputStringBuilder.append((char) currentByte);
}
Well, the problem with your second attempt is that you read two hex characters at a time (which is correct, since each pair of hex characters is a single byte), but your loop condition and increment are wrong.
Try this:
StringBuilder sb = new StringBuilder ();
for (int i = 0; i < input.length()/2; i+=2) {
String s = input.substring(i, i + 2);
byte value = Byte.valueOf(s, 16);
sb.append(value);
}
In addition you should also check that the input has an even number of hex characters.
EDIT
I changed $checksum = md5($someString+$bkey); to $checksum = md5($someString.$bkey);
I need to perform the following operations in Java:
$hexString = '90aa';#sample value
$bkey = pack('H*',$hexString);
$someString='qwe';#sample value
$checksum = md5($someString.$bkey);
echo $checksum;
I can't convert hexString to bkey in Java to get the same result as php script. Except bkey everything is working properly.
If I remove bkey then:
PHP:
$someString='qwe';#sample value
$checksum = md5($someString);
echo $checksum;
result: 76d80224611fc919a5d54f0ff9fba446
Java:
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
String checksum = new BigInteger(1, messageDigest.digest(someString
.getBytes())).toString(16);
System.out.println(checksum);
result: 76d80224611fc919a5d54f0ff9fba446
As you can see, it works
With bkey:
PHP:
$hexString = '90aa';#sample value
$bkey = pack('H*',$hexString);
$someString='qwe';#sample value
$checksum = md5($someString.$bkey);
echo $checksum;
result: 18f5f1a9bf898131945dd9e315759fe4
Java:
public static void main(String[] args) throws NoSuchAlgorithmException {
String hexString = "90aa";
String bkey = hexToString(hexString);
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
String input = someString + bkey;
String checksum = new BigInteger(1, messageDigest.digest(input
.getBytes())).toString(16);
System.out.println(checksum);
}
public static String hexToString(String hex) {
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));
}
return output.toString();
}
result: 44bb634dee436833dd65caa5043ffeb9
As you can see results are different.
How to convert hex String to String to get the same result?
The problem is not actually in your Java code, but in the PHP code.
The line $checksum = md5($someString+$bkey); does not do what you think it does, it should be:
$checksum = md5($someString . $bkey); # use concatenate, not sum
Although, that gives abetter PHP MD5, but does not help make the Java code match the PHP
EDIT
The problem on the Java side is in the character encoding. The Java char values for the inoacked versions of 90aa are not valid unicode characters. Thus the toByteArray() ,ethods ar enot doing great things. If you treat all of the Java code at a byte level (and ignore any high-bytes in any chars in the Java), then you get the same result as the PHP:
public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String hexString = "90aa";
byte[] bkey = hexToString(hexString);
String someString = "qwe";
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] input = join(stringToBytes(someString), bkey);
String checksum = new BigInteger(1, messageDigest.digest(input)).toString(16);
System.out.println(checksum);
System.out.println(Charset.defaultCharset().displayName());
}
private static byte[] join(byte[] a, byte[] b) {
// join two byte arrays
final byte[] ret = new byte[a.length + b.length];
System.arraycopy(a, 0, ret, 0, a.length);
System.arraycopy(b, 0, ret, a.length, b.length);
return ret;
}
public static byte[] hexToString(String hex) {
// hexToString that works at a byte level, not a character level
byte[] output = new byte[(hex.length() + 1) / 2];
for (int i = hex.length() - 1; i >= 0; i -= 2) {
int from = i - 1;
if (from < 0) {
from = 0;
}
String str = hex.substring(from, i + 1);
output[i/2] = (byte)Integer.parseInt(str, 16);
}
return output;
}
public static byte[] stringToBytes(final String input) {
// unlike Stirng.toByteArray(), we ignore any high-byte values of the characters.
byte[] ret = new byte[input.length()];
for (int i = input.length() - 1; i >=0; i--) {
ret[i] = (byte)input.charAt(i);
}
return ret;
}
The above Java code produces the MD5sum 18f5f1a9bf898131945dd9e315759fe4 which is what PHP gives too
as the title says, how do I do it? Its easy to convert from string -> byte -> string binary, But how do I convert back? Below is a example.
The output is :
'f' to binary: 01100110
294984
I read somewhere that I could use the Integer.parseInt but clearly that is not the case :( Or am I doing something wrong?
Thanks,
:)
public class main{
public static void main(String[] args) {
String s = "f";
byte[] bytes = s.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes)
{
int val = b;
for (int i = 0; i < 8; i++)
{
binary.append((val & 128) == 0 ? 0 : 1);
val <<= 1;
}
binary.append(' ');
}
System.out.println("'" + s + "' to binary: " + binary);
System.out.println(Integer.parseInt("01100110", 2));
}
}
You can use Byte.parseByte() with a radix of 2:
byte b = Byte.parseByte(str, 2);
Using your example:
System.out.println(Byte.parseByte("01100110", 2));
102
You can parse it to an integer in base 2, and convert to a byte array.
In your example you've got 16 bits you can also use short.
short a = Short.parseShort(b, 2);
ByteBuffer bytes = ByteBuffer.allocate(2).putShort(a);
byte[] array = bytes.array();
Just in case if you need it for a Very Big String.
String b = "0110100001101001";
byte[] bval = new BigInteger(b, 2).toByteArray();
I made like this, converted a string s -> byte[] and then used Integer.toBinaryString to get binaryStringRep. I converted bianryStringRep by using Byte.parseByte to get the bianryStringRep into byte and the String(newByte[]) to get the byte[] into a String! Hope it helps others then me aswell! ^^
public class main{
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "foo";
byte[] bytes = s.getBytes();
byte[] newBytes = new byte[s.getBytes().length];
for(int i = 0; i < bytes.length; i++){
String binaryStringRep = String.format("%8s", Integer.toBinaryString(bytes[i] & 0xFF)).replace(' ', '0');
byte newByte = Byte.parseByte(binaryStringRep, 2);
newBytes[i] = newByte;
}
String str = new String(newBytes, "UTF-8");
System.out.println(str);
}
}
I am working on Socket connection. I am working on the client side.
I have gone through this discussion Socket pass value as Hex. I need to send the String e.g(0x01 is a hex value and a String "Ravi") at the server they are expecting hexa value like 1 72 61 76 69. I tried of converting String Ravi to hexa value as String and appending "1" and try to convert to byte array. I am getting an exception that StringIndexOutOfBound exception.
update:
`public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 2)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public String toHex(String arg) {
return String.format("%x", new BigInteger(arg.getBytes()));
}`
I used these two methods to convert the 1Ravi string to byte array but i am getting exception hexstringtobytearray method.
try this
Socket sock = new Socket("host", port);
OutputStream out = sock.getOutputStream();
out.write(0);
String s = "ravi";
byte[] bytes = s.getBytes("UTF-8");
out.write(bytes);
I am trying to convert a string like "testing123" into hexadecimal form in java. I am currently using BlueJ.
And to convert it back, is it the same thing except backward?
Here's a short way to convert it to hex:
public String toHex(String arg) {
return String.format("%040x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
To ensure that the hex is always 40 characters long, the BigInteger has to be positive:
public String toHex(String arg) {
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
import org.apache.commons.codec.binary.Hex;
...
String hexString = Hex.encodeHexString(myString.getBytes(/* charset */));
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html
Use DatatypeConverter.printHexBinary():
public static String toHexadecimal(String text) throws UnsupportedEncodingException
{
byte[] myBytes = text.getBytes("UTF-8");
return DatatypeConverter.printHexBinary(myBytes);
}
Example usage:
System.out.println(toHexadecimal("Hello StackOverflow"));
Prints:
48656C6C6F20537461636B4F766572666C6F77
Note: This causes a little extra trouble with Java 9 and newer since the API is not included by default. For reference e.g. see this GitHub issue.
The numbers that you encode into hexadecimal must represent some encoding of the characters, such as UTF-8. So first convert the String to a byte[] representing the string in that encoding, then convert each byte to hexadecimal.
public static String hexadecimal(String input, String charsetName) throws UnsupportedEncodingException {
if (input == null) throw new NullPointerException();
return asHex(input.getBytes(charsetName));
}
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
public static String asHex(byte[] buf)
{
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
Here an other solution
public static String toHexString(byte[] ba) {
StringBuilder str = new StringBuilder();
for(int i = 0; i < ba.length; i++)
str.append(String.format("%x", ba[i]));
return str.toString();
}
public static String fromHexString(String hex) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
str.append((char) Integer.parseInt(hex.substring(i, i + 2), 16));
}
return str.toString();
}
All answers based on String.getBytes() involve encoding your string according to a Charset. You don't necessarily get the hex value of the 2-byte characters that make up your string. If what you actually want is the equivalent of a hex viewer, then you need to access the chars directly. Here's the function that I use in my code for debugging Unicode issues:
static String stringToHex(String string) {
StringBuilder buf = new StringBuilder(200);
for (char ch: string.toCharArray()) {
if (buf.length() > 0)
buf.append(' ');
buf.append(String.format("%04x", (int) ch));
}
return buf.toString();
}
Then, stringToHex("testing123") will give you:
0074 0065 0073 0074 0069 006e 0067 0031 0032 0033
byte[] bytes = string.getBytes(CHARSET); // you didn't say what charset you wanted
BigInteger bigInt = new BigInteger(bytes);
String hexString = bigInt.toString(16); // 16 is the radix
You could return hexString at this point, with the caveat that leading null-chars will be stripped, and the result will have an odd length if the first byte is less than 16. If you need to handle those cases, you can add some extra code to pad with 0s:
StringBuilder sb = new StringBuilder();
while ((sb.length() + hexString.length()) < (2 * bytes.length)) {
sb.append("0");
}
sb.append(hexString);
return sb.toString();
To get the Integer value of hex
//hex like: 0xfff7931e to int
int hexInt = Long.decode(hexString).intValue();
I would suggest something like this, where str is your input string:
StringBuffer hex = new StringBuffer();
char[] raw = tokens[0].toCharArray();
for (int i=0;i<raw.length;i++) {
if (raw[i]<=0x000F) { hex.append("000"); }
else if(raw[i]<=0x00FF) { hex.append("00" ); }
else if(raw[i]<=0x0FFF) { hex.append("0" ); }
hex.append(Integer.toHexString(raw[i]).toUpperCase());
}
Java 17 introduces a utility class for hexadecimal formatting: java.util.HexFormat
Convert to hex:
public String toHex(String value) {
return HexFormat.of().formatHex(value.getBytes());
}
Convert from hex:
public String fromHex(String value) {
return new String(HexFormat.of().parseHex(value));
}
More about HexFormat here
Documentation: here
Convert a letter in hex code and hex code in letter.
String letter = "a";
String code;
int decimal;
code = Integer.toHexString(letter.charAt(0));
decimal = Integer.parseInt(code, 16);
System.out.println("Hex code to " + letter + " = " + code);
System.out.println("Char to " + code + " = " + (char) decimal);
To go the other way (hex to string), you can use
public String hexToString(String hex) {
return new String(new BigInteger(hex, 16).toByteArray());
}
One line HEX encoding/decoding without external libs (Java 8 and above):
Encoding :
String hexString = inputString.chars().mapToObj(c ->
Integer.toHexString(c)).collect(Collectors.joining());
Decoding :
String decodedString = Stream.iterate(0, i -> i+2)
.limit(hexString.length()/2 + Math.min(hexString.length()%2,1))
.map(i -> "" + (char)Integer.parseInt("" + hexString.charAt(i) + hexString.charAt(i+1),16))
.collect(Collectors.joining());
First convert it into bytes using getBytes() function and then convert it into hex usign this :
private static String hex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<bytes.length; i++) {
sb.append(String.format("%02X ",bytes[i]));
}
return sb.toString();
}
Using Multiple Peoples help from multiple Threads..
I know this has been answered, but i would like to give a full encode & decode method for any others in my same situation..
Here's my Encoding & Decoding methods..
// Global Charset Encoding
public static Charset encodingType = StandardCharsets.UTF_8;
// Text To Hex
public static String textToHex(String text)
{
byte[] buf = null;
buf = text.getBytes(encodingType);
char[] HEX_CHARS = "0123456789abcdef".toCharArray();
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
{
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
}
return new String(chars);
}
// Hex To Text
public static String hexToText(String hex)
{
int l = hex.length();
byte[] data = new byte[l / 2];
for (int i = 0; i < l; i += 2)
{
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
String st = new String(data, encodingType);
return st;
}
Much better:
public static String fromHexString(String hex, String sourceEncoding ) throws IOException{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int _start=0;
for (int i = 0; i < hex.length(); i+=2) {
buffer[_start++] = (byte)Integer.parseInt(hex.substring(i, i + 2), 16);
if (_start >=buffer.length || i+2>=hex.length()) {
bout.write(buffer);
Arrays.fill(buffer, 0, buffer.length, (byte)0);
_start = 0;
}
}
return new String(bout.toByteArray(), sourceEncoding);
}
import java.io.*;
import java.util.*;
public class Exer5{
public String ConvertToHexadecimal(int num){
int r;
String bin="\0";
do{
r=num%16;
num=num/16;
if(r==10)
bin="A"+bin;
else if(r==11)
bin="B"+bin;
else if(r==12)
bin="C"+bin;
else if(r==13)
bin="D"+bin;
else if(r==14)
bin="E"+bin;
else if(r==15)
bin="F"+bin;
else
bin=r+bin;
}while(num!=0);
return bin;
}
public int ConvertFromHexadecimalToDecimal(String num){
int a;
int ctr=0;
double prod=0;
for(int i=num.length(); i>0; i--){
if(num.charAt(i-1)=='a'||num.charAt(i-1)=='A')
a=10;
else if(num.charAt(i-1)=='b'||num.charAt(i-1)=='B')
a=11;
else if(num.charAt(i-1)=='c'||num.charAt(i-1)=='C')
a=12;
else if(num.charAt(i-1)=='d'||num.charAt(i-1)=='D')
a=13;
else if(num.charAt(i-1)=='e'||num.charAt(i-1)=='E')
a=14;
else if(num.charAt(i-1)=='f'||num.charAt(i-1)=='F')
a=15;
else
a=Character.getNumericValue(num.charAt(i-1));
prod=prod+(a*Math.pow(16, ctr));
ctr++;
}
return (int)prod;
}
public static void main(String[] args){
Exer5 dh=new Exer5();
Scanner s=new Scanner(System.in);
int num;
String numS;
int choice;
System.out.println("Enter your desired choice:");
System.out.println("1 - DECIMAL TO HEXADECIMAL ");
System.out.println("2 - HEXADECIMAL TO DECIMAL ");
System.out.println("0 - EXIT ");
do{
System.out.print("\nEnter Choice: ");
choice=s.nextInt();
if(choice==1){
System.out.println("Enter decimal number: ");
num=s.nextInt();
System.out.println(dh.ConvertToHexadecimal(num));
}
else if(choice==2){
System.out.println("Enter hexadecimal number: ");
numS=s.next();
System.out.println(dh.ConvertFromHexadecimalToDecimal(numS));
}
}while(choice!=0);
}
}
new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)
Here are some benchmarks comparing different approaches and libraries. Guava beats Apache Commons Codec at decoding. Commons Codec beats Guava at encoding. And JHex beats them both for decoding and encoding.
JHex example
String hexString = "596f752772652077656c636f6d652e";
byte[] decoded = JHex.decodeChecked(hexString);
System.out.println(new String(decoded));
String reEncoded = JHex.encode(decoded);
Everything is in a single class file for JHex. Feel free to copy paste if you don't want yet another library in your dependency tree. Also note, it is only available as Java 9 jar until I can figure out how to publish multiple release targets with Gradle and the Bintray plugin.
Convert String to Hexadecimal:
public String hexToString(String hex) {
return Integer.toHexString(Integer.parseInt(hex));
}
definitely this is the easy way.
check this solution for String to hex and hex to String vise-versa
public class TestHexConversion {
public static void main(String[] args) {
try{
String clearText = "testString For;0181;with.love";
System.out.println("Clear Text = " + clearText);
char[] chars = clearText.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
hex.append(Integer.toHexString((int) chars[i]));
}
String hexText = hex.toString();
System.out.println("Hex Text = " + hexText);
String decodedText = HexToString(hexText);
System.out.println("Decoded Text = "+decodedText);
} catch (Exception e){
e.printStackTrace();
}
}
public static String HexToString(String hex){
StringBuilder finalString = new StringBuilder();
StringBuilder tempString = 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);
finalString.append((char)decimal);
tempString.append(decimal);
}
return finalString.toString();
}
Output as follows :
Clear Text = testString For;0181;with.love
Hex Text = 74657374537472696e6720466f723b303138313b776974682e6c6f7665
Decoded Text = testString For;0181;with.love
A short and convenient way to convert a String to its Hexadecimal notation is:
public static void main(String... args){
String str = "Hello! This is test string.";
char ch[] = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length; i++) {
sb.append(Integer.toHexString((int) ch[i]));
}
System.out.println(sb.toString());
}