Konvertieren eines Strings in Hexadezimal In Java


107

Ich versuche, eine Zeichenfolge wie "testing123" in Java in hexadezimale Form umzuwandeln. Ich benutze derzeit BlueJ.

Und um es zurück zu konvertieren, ist es dasselbe, außer rückwärts?

java  string  hex 

Bitte bearbeiten Sie Ihre Frage, um den Code anzuzeigen , den Sie bisher haben . Sie sollten mindestens eine Gliederung (aber vorzugsweise ein minimal reproduzierbares Beispiel ) des Codes einfügen, mit dem Sie Probleme haben. Dann können wir versuchen, bei dem spezifischen Problem zu helfen. Sie sollten auch lesen, wie man fragt .
Toby Speight

Antworten:


201

Hier ist eine kurze Möglichkeit, es in Hex umzuwandeln:

public String toHex(String arg) {
    return String.format("%040x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}

24
+1 auf die reinste Probe von 3vilness, die ich je gesehen habe: Verwenden einer BigInteger zum Konvertieren von einem Byte [] ...
Eduardo Costa

13
Liebe es! Keine Loops und kein Bit-Flipping. Ich möchte Ihnen 0xFF Upvotes geben :)
Laher

5
Um 40 Zeichen zu gewährleisten, sollten Sie keine Auffüllung hinzufügen: return String.format ("% 040x", neue BigInteger (arg.getBytes (/ * YOUR_CHARSET? * /)));
Ron

4
@Kaleb Hast du eine Idee, wenn möglich, den resultierenden String zurück zu konvertieren? Wenn ja, können Sie mir einige Hinweise geben? Vielen Dank!
Artaxerxe

1
Sie müssen den BigInteger(int,byte[])Konstruktor verwenden. Andernfalls erhalten Sie eine negative BigInteger, wenn das erste Byte negativ ist.
Joni

62

Um sicherzustellen, dass das Hex immer 40 Zeichen lang ist, muss die BigInteger positiv sein:

public String toHex(String arg) {
  return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}

1
Diese Methode ist eigentlich die richtige. Der Try- byte[] data = { -1, 1 };Code in dieser Antwort funktioniert einwandfrei, während der mit 17 Upvotes fehlschlägt.
Hudolejev

1
Ist es möglich, ein Byte mit Wert -1aus einer Zeichenfolge abzurufen (wie im Beispiel angefordert)?
Kaleb Pederson

@KalebPederson Ja. Es ist nicht einmal sehr schwer. . Wenn Ihre gewählte Codierung jemals das höchstwertige Bit eines Zeichens verwendet (z. B. UTF- * do), haben Sie negative bytes in Ihrem Array.
Fund Monica Klage

45
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


3
Interessant, wenn Sie das Rad nicht neu erfinden wollen.
Federico Zancan

3
@ MelNicholson Es gibt eine decodeHex-Funktion in Hex, um zu einem Byte [] zu gelangen. Sie müssen dies verwenden, da nichts garantiert, dass eine zufällige HEX-Zeichenfolge in eine Zeichenfolge in Ihrer Codierung konvertiert werden kann.
BxlSofty

18

Die Zahlen, die Sie hexadezimal codieren, müssen eine Codierung der Zeichen darstellen, z. B. UTF-8. Konvertieren Sie also zuerst den String in ein Byte [], das den String in dieser Codierung darstellt, und konvertieren Sie dann jedes Byte in hexadezimal.

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);
}

Dies ist eine interessante Lösung, die den Kern der digitalen Darstellung von Daten berührt. Könnten Sie bitte erklären, was Sie tun und was die "magischen Zahlen" in Ihrer Lösung darstellen? Ein Neuling weiß möglicherweise nicht, was der Operator >>> bedeutet, warum wir das bitweise-und & zusammen mit einer Maske von 0xF0 verwenden oder warum das Zeichen-Array die Größe [2 * buf.length] hat.
Boris

16

Verwendung DatatypeConverter.printHexBinary():

public static String toHexadecimal(String text) throws UnsupportedEncodingException
{
    byte[] myBytes = text.getBytes("UTF-8");

    return DatatypeConverter.printHexBinary(myBytes);
}

Anwendungsbeispiel:

System.out.println(toHexadecimal("Hello StackOverflow"));

Drucke:

48656C6C6F20537461636B4F766572666C6F77

Hinweis : Dies verursacht zusätzliche Probleme mit Java 9und neueren Versionen, da die API standardmäßig nicht enthalten ist. Als Referenz siehe zB diese GitHub Ausgabe.


11

Hier eine andere Lösung

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();
}

3
Schön, aber ich würde format("%02x")so verwenden, dass format () immer 2 Zeichen verwendet. Obwohl ASCII zweistellig hexadezimal ist, dh A = 0x65
Mike Jones

8

Alle Antworten, die auf String.getBytes () basieren, beinhalten die Codierung Ihres Strings gemäß einem Zeichensatz. Sie erhalten nicht unbedingt den Hex-Wert der 2-Byte- Zeichen , aus denen Ihre Zeichenfolge besteht. Wenn das, was Sie tatsächlich wollen, einem Hex-Viewer entspricht, müssen Sie direkt auf die Zeichen zugreifen. Hier ist die Funktion, die ich in meinem Code zum Debuggen von Unicode-Problemen verwende:

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();
}

Dann gibt Ihnen stringToHex ("testing123"):

0074 0065 0073 0074 0069 006e 0067 0031 0032 0033

Dies ist in Ordnung, wenn Sie die interne Darstellung der Java-Zeichen sehen möchten, nämlich UTF-16, eine spezifische Darstellung von Unicode.
Jonathan Rosenne

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

Sie können hexStringan dieser Stelle mit der Einschränkung zurückkehren, dass führende Nullzeichen entfernt werden und das Ergebnis eine ungerade Länge hat, wenn das erste Byte kleiner als 16 ist. Wenn Sie diese Fälle behandeln müssen, können Sie zusätzlichen Code hinzufügen mit 0s auffüllen:

StringBuilder sb = new StringBuilder();
while ((sb.length() + hexString.length()) < (2 * bytes.length)) {
  sb.append("0");
}
sb.append(hexString);
return sb.toString();

5

Um den Integer-Wert von hex zu erhalten

        //hex like: 0xfff7931e to int
        int hexInt = Long.decode(hexString).intValue();

5

Konvertieren Sie einen Buchstaben in Hex-Code und Hex-Code in Buchstaben.

        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);

5

Ich würde so etwas vorschlagen, wo strist Ihre Eingabezeichenfolge:

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());
}

Vielen Dank für die Korrektur, Software Monkey. Ich war ziemlich müde, als ich die Antwort schrieb, und mein Test für 'raw [i] <= 9' ist eindeutig unzureichend.
Rodion

1
Das funktioniert wirklich gut. Gibt es eine Möglichkeit, das generierte Hex wieder in einen String umzukehren?

1
Wo ist str darin?
Viswanath Lekshmanan

3

Konvertieren Sie es zuerst mit der Funktion getBytes () in Bytes und konvertieren Sie es dann in hexadezimales Zeichen.

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();
}

3

Um den anderen Weg zu gehen (hex zu string), können Sie verwenden

public String hexToString(String hex) {
    return new String(new BigInteger(hex, 16).toByteArray());
}

1
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);
    }
}

1
new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)

1

String in Hexadezimal konvertieren :

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

Auf jeden Fall ist dies der einfache Weg.


Dies ist keine Lösung. Die Frage lautet, wie die hexadezimale Darstellung des Inhalts eines beliebigen Strings abgerufen werden kann , und es wird speziell "testing123" als Beispiel angegeben.
Skomisa

1

Verwenden mehrerer Völker Hilfe von mehreren Threads.

Ich weiß, dass dies beantwortet wurde, aber ich möchte eine vollständige Codierungs- und Decodierungsmethode für alle anderen in meiner gleichen Situation angeben.

Hier sind meine Kodierungs- und Dekodierungsmethoden.

// 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;
}

Nett! Nur in Zeile 13 sollte ">>>" ">>" sein
spikeyang

0

Viel besser:

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

Hier sind einige Benchmarks , die verschiedene Ansätze und Bibliotheken vergleichen. Guave schlägt Apache Commons Codec beim Dekodieren. Commons Codec schlägt Guava bei der Codierung. Und JHex schlägt sie beide beim Dekodieren und Kodieren.

JHex Beispiel

String hexString = "596f752772652077656c636f6d652e";
byte[] decoded = JHex.decodeChecked(hexString);
System.out.println(new String(decoded));
String reEncoded = JHex.encode(decoded);

Alles ist in einer einzigen Klassendatei für JHex . Sie können das Einfügen kopieren, wenn Sie keine weitere Bibliothek in Ihrem Abhängigkeitsbaum haben möchten. Beachten Sie auch, dass es nur als Java 9-JAR verfügbar ist, bis ich herausgefunden habe, wie mehrere Release-Ziele mit Gradle und dem Bintray-Plugin veröffentlicht werden können.


0

Eine kurze und bequeme Möglichkeit, einen String in seine hexadezimale Notation umzuwandeln, ist:

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());
}

0

Überprüfen Sie diese Lösung auf String to hex und Hex to String umgekehrt

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();
}

Ausgabe wie folgt:

Klartext = testString For; 0181; with.love

Hex-Text = 74657374537472696e6720466f723b303138313b776974682e6c6f7665

Decodierter Text = testString For; 0181; with.love

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.