120

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?

23 Answers23

225

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?*/)));
}
Joni
  • 108,737
  • 14
  • 143
  • 193
Kaleb Pederson
  • 45,767
  • 19
  • 102
  • 147
  • 29
    +1 to the most pure sample of 3vilness I ever saw: using a BigInteger to convert from a byte[]... – Eduardo Costa Jul 05 '11 at 21:07
  • 16
    Love it! No loops and no bit-flipping. I want to give you 0xFF upvotes :) – laher Oct 22 '11 at 23:11
  • 5
    to ensure 40 Characters, you should add zero padding: return String.format("%040x", new BigInteger(arg.getBytes(/*YOUR_CHARSET?*/))); – Ron Nov 07 '11 at 14:49
  • what about converting negative values which use 8 Characters and want them to fit in only 4? – Roman Rdgz Nov 09 '11 at 12:08
  • 6
    @Kaleb Have you idea if possible to convert resulted String back? If, yes, can you give me some hints? Thanks! – artaxerxe Apr 11 '12 at 10:06
  • Just add if(arg.equals("")){return ""} before the return line. – Ben Holland Jan 08 '13 at 21:41
  • 2
    You have to use the `BigInteger(int,byte[])` constructor; otherwise if the first byte is negative you get a negative BigInteger. – Joni Sep 22 '13 at 13:33
  • 1
    I had a `byte[] bytes` as input, and landed on this answer. This is what you need in this case: `return bytes.length == 0 ? "" : String.format("%0" + (bytes.length * 2) + "x", new BigInteger(1, bytes));` – Walter Tross Jul 23 '14 at 12:40
  • 1
    How to do the reverse - hex to String? – Jasper Sep 27 '15 at 09:04
  • 1
    Please don't use this "solution", it's by far the slowest way to do this kind of conversion. – BluEOS Aug 23 '20 at 09:50
  • 2
    It can lose the first `0`, for example for SHA512(SHA512("hello")) it starts with `592a` while should start with `0592`. – KeyKi Aug 09 '21 at 19:08
68

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?*/)));
}
Jos Theeuwen
  • 899
  • 1
  • 7
  • 8
  • 1
    This method is actually the correct one. Try `byte[] data = { -1, 1 };` -- code in this answer works fine, whereas that with 17 upvotes fails. – hudolejev Mar 01 '12 at 23:36
  • 1
    Is it possible to get a byte with value `-1` out of a string (as was requested in the example)? – Kaleb Pederson Jan 09 '13 at 17:10
  • @KalebPederson [Yes. It's not even very hard.](https://www.ideone.com/SXaeVY). If your chosen encoding _ever_ uses the most significant bit of any character (say, like UTF-\* do), you have negative `byte`s in your array. – Nic Oct 18 '18 at 00:38
57
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

Joshua Swink
  • 3,380
  • 3
  • 29
  • 27
  • 4
    Interesting, if you don't want to reinvent the wheel. – Federico Zancan Nov 16 '12 at 12:10
  • 3
    @MelNicholson there's a decodeHex function in Hex to go to a byte[]. You need to use that because nothing guarantees that a random HEX string can be converted to a string in your encoding. – BxlSofty Oct 28 '14 at 07:36
22

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.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
21

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);
}
Stephen Denne
  • 36,219
  • 10
  • 45
  • 60
  • This is an interesting solution and one that strikes at the core of digital representation of data. Could you please explain what you are doing though, and what the "magic numbers" in your solution represent? A newcomer may not know what the >>> operator means, why we use the bitwise-and & along with a mask of 0xF0, or why the chars array is of size [2 * buf.length]. – Boris Sep 16 '19 at 04:54
12

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();
}
jordeu
  • 6,711
  • 1
  • 19
  • 19
  • 3
    Nice but I would use `format("%02x")` so format() always uses 2 chars. Even though ASCII is double digit hex ie A=0x65 – mike jones Feb 07 '13 at 17:58
11

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

S. Florin
  • 375
  • 3
  • 15
8

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
Bogdan Calmac
  • 7,993
  • 6
  • 51
  • 64
  • 1
    This is fine if what you want is to see the internal representation of the Java characters, which is UTF-16, a specific representation of Unicode. – Jonathan Rosenne Sep 09 '18 at 20:16
  • 1
    This prints leading zeroes even if they are not actually in memory. Java does [not](https://openjdk.java.net/jeps/254) always use UTF-16 anymore. – Martin Oct 01 '20 at 19:58
5

To get the Integer value of hex

        //hex like: 0xfff7931e to int
        int hexInt = Long.decode(hexString).intValue();
TouchBoarder
  • 6,422
  • 2
  • 52
  • 60
5

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());
}
Giulio Muscarello
  • 1,312
  • 2
  • 12
  • 33
rodion
  • 6,087
  • 4
  • 24
  • 29
5
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();
Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
4

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);
Marcus Becker
  • 352
  • 4
  • 11
4

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());
ouflak
  • 2,458
  • 10
  • 44
  • 49
3

To go the other way (hex to string), you can use

public String hexToString(String hex) {
    return new String(new BigInteger(hex, 16).toByteArray());
}
Jojodmo
  • 23,357
  • 13
  • 65
  • 107
Jibby
  • 850
  • 1
  • 9
  • 21
3

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;
}
Empire of E
  • 588
  • 6
  • 12
2

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();
}
user2475511
  • 79
  • 1
  • 7
0

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);
}
0
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);
    }
}
Tisho
  • 8,320
  • 6
  • 44
  • 52
0
new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)
ultraon
  • 2,220
  • 2
  • 28
  • 27
0

Convert String to Hexadecimal:

public String hexToString(String hex) {
    return Integer.toHexString(Integer.parseInt(hex));
}

definitely this is the easy way.

Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • This is not a solution. The question is asking how to get the hex representation of the content of an arbitrary String, and specifically provided _"testing123"_ as an example. – skomisa Feb 28 '19 at 06:27
0

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.

Community
  • 1
  • 1
0

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

Community
  • 1
  • 1
Nitin Upadhyay
  • 113
  • 1
  • 15
-1

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());
}
Amit Samuel
  • 109
  • 1
  • 5