Mengubah String Menjadi Heksadesimal Di Jawa

107

Saya mencoba untuk mengubah string seperti "testing123" menjadi bentuk heksadesimal di java. Saya saat ini menggunakan BlueJ.

Dan untuk mengubahnya kembali, apakah itu sama kecuali mundur?


sumber
Harap edit pertanyaan Anda untuk menunjukkan kode yang Anda miliki sejauh ini . Anda harus menyertakan setidaknya garis besar (tetapi lebih disukai contoh minimal yang dapat direproduksi ) dari kode yang bermasalah, kemudian kami dapat mencoba membantu dengan masalah spesifik tersebut. Anda juga harus membaca Cara Bertanya .
Toby Speight

Jawaban:

201

Berikut cara singkat untuk mengubahnya menjadi hex:

public String toHex(String arg) {
    return String.format("%040x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
Kaleb Pederson
sumber
24
+1 ke sampel paling murni dari 3vilness yang pernah saya lihat: menggunakan BigInteger untuk mengonversi dari byte [] ...
Eduardo Costa
13
Suka! Tidak ada loop dan tidak ada bit-flipping. Saya ingin memberi Anda
suara positif
5
untuk memastikan 40 Karakter, Anda harus menambahkan padding nol: return String.format ("% 040x", BigInteger baru (arg.getBytes (/ * YOUR_CHARSET? * /)));
Ron
4
@Kaleb Apakah Anda tahu jika mungkin untuk mengubah String yang dihasilkan kembali? Jika ya, dapatkah Anda memberi saya beberapa petunjuk? Terima kasih!
artaxerxe
1
Anda harus menggunakan BigInteger(int,byte[])konstruktor; sebaliknya jika byte pertama negatif Anda mendapatkan BigInteger negatif.
Joni
62

Untuk memastikan bahwa hex selalu terdiri dari 40 karakter, BigInteger harus positif:

public String toHex(String arg) {
  return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
}
Jos Theeuwen
sumber
1
Cara ini sebenarnya yang benar. Coba byte[] data = { -1, 1 };- kode dalam jawaban ini berfungsi dengan baik, sedangkan dengan 17 suara positif gagal.
hudolejev
1
Apakah mungkin untuk mendapatkan byte dengan nilai -1dari sebuah string (seperti yang diminta dalam contoh)?
Kaleb Pederson
@KalebPederson Ya. Ini bahkan tidak terlalu sulit. . Jika pengkodean yang Anda pilih pernah menggunakan bit paling signifikan dari karakter apa pun (misalnya, seperti UTF- * do), Anda memiliki bytes negatif dalam larik Anda.
Dana Gugatan Monica
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

Joshua Swink
sumber
3
Menarik, jika Anda tidak ingin menemukan kembali kemudi.
Federico Zancan
3
@MelNicholson ada fungsi decodeHex di Hex untuk pergi ke byte []. Anda perlu menggunakannya karena tidak ada yang menjamin bahwa string HEX acak dapat diubah menjadi string dalam pengkodean Anda.
BxlSofty
18

Angka yang Anda enkode menjadi heksadesimal harus mewakili beberapa pengkodean karakter, seperti UTF-8. Jadi pertama-tama ubah String menjadi byte [] yang mewakili string dalam pengkodean itu, kemudian ubah setiap byte menjadi heksadesimal.

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
sumber
Ini adalah solusi yang menarik dan yang menyerang inti representasi digital dari data. Bisakah Anda menjelaskan apa yang Anda lakukan, dan apa yang diwakili oleh "angka ajaib" dalam solusi Anda? Seorang pendatang baru mungkin tidak tahu apa arti operator >>>, mengapa kita menggunakan bitwise-and & bersama dengan mask 0xF0, atau mengapa array karakter berukuran [2 * buf.length].
Boris
16

Penggunaan DatatypeConverter.printHexBinary():

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

    return DatatypeConverter.printHexBinary(myBytes);
}

Contoh penggunaan:

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

Cetakan:

48656C6C6F20537461636B4F766572666C6F77

Catatan : Ini menyebabkan sedikit masalah ekstra dengan Java 9dan yang lebih baru karena API tidak disertakan secara default. Untuk referensi, misalnya lihat masalah ini GitHub .

BullyWiiPlaza
sumber
11

Berikut solusi lain

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
sumber
3
Bagus tapi saya akan menggunakan format("%02x")jadi format () selalu menggunakan 2 karakter. Meskipun ASCII adalah hex digit ganda yaitu A = 0x65
mike jones
8

Semua jawaban berdasarkan String.getBytes () melibatkan pengkodean string Anda sesuai dengan Charset. Anda tidak perlu mendapatkan nilai hex dari 2-byte karakter yang membentuk string Anda. Jika yang Anda inginkan sebenarnya setara dengan hex viewer, maka Anda perlu mengakses karakternya secara langsung. Inilah fungsi yang saya gunakan dalam kode saya untuk men-debug masalah Unicode:

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

Kemudian, stringToHex ("testing123") akan memberi Anda:

0074 0065 0073 0074 0069 006e 0067 0031 0032 0033
Bogdan Calmac
sumber
Ini bagus jika yang Anda inginkan adalah melihat representasi internal dari karakter Java, yaitu UTF-16, representasi Unicode tertentu.
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

Anda dapat kembali hexStringpada titik ini, dengan peringatan bahwa karakter null terkemuka akan dihilangkan, dan hasilnya akan memiliki panjang ganjil jika byte pertama kurang dari 16. Jika Anda perlu menangani kasus tersebut, Anda dapat menambahkan beberapa kode tambahan untuk diisi dengan 0s:

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

Untuk mendapatkan nilai Integer dari hex

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

Ubah huruf menjadi kode hex dan kode hex dalam huruf.

        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
sumber
5

Saya akan menyarankan sesuatu seperti ini, di mana strstring input Anda:

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());
}
rodion
sumber
Terima kasih atas koreksinya, Software Monkey. Saya cukup lelah ketika menulis jawabannya, dan tes saya untuk 'mentah [i] <= 9' jelas tidak cukup.
rodion
1
Ini bekerja dengan sangat baik, apakah ada cara untuk membalikkan hex yang dihasilkan kembali ke string lagi?
1
Dimana str ini?
Viswanath Lekshmanan
3

Pertama ubah menjadi byte menggunakan fungsi getBytes () dan kemudian ubah menjadi hex gunakan ini:

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

Untuk pergi ke arah lain (hex ke string), Anda bisa menggunakan

public String hexToString(String hex) {
    return new String(new BigInteger(hex, 16).toByteArray());
}
Jibby
sumber
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);
    }
}
Rowena Jimenez
sumber
1
new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)
ultraon
sumber
1

Ubah String menjadi Heksadesimal :

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

pasti ini cara yang mudah.

Jorgesys
sumber
Ini bukanlah solusi. Pertanyaannya adalah menanyakan bagaimana mendapatkan representasi hex dari konten String arbitrer, dan secara khusus menyediakan "testing123" sebagai contoh.
skomisa
1

Menggunakan bantuan Banyak Orang dari beberapa Utas ..

Saya tahu ini telah dijawab, tetapi saya ingin memberikan metode encode & decode lengkap untuk orang lain dalam situasi yang sama ..

Inilah metode Encoding & Decoding saya ..

// 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;
}
Gadget Guru
sumber
Bagus! Hanya di baris 13, ">>>" harus ">>"
spikeyang
0

Jauh lebih baik:

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);
}
Dmitriy Bocharov
sumber
0

Berikut adalah beberapa tolok ukur yang membandingkan pendekatan dan pustaka yang berbeda. Guava mengalahkan Apache Commons Codec saat mendekode. Commons Codec mengalahkan Jambu dalam pengkodean. Dan JHex mengalahkan keduanya untuk decoding dan encoding.

Contoh JHex

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

Semuanya ada dalam satu file kelas untuk JHex . Jangan ragu untuk menyalin dan menempel jika Anda tidak menginginkan pustaka lain di pohon ketergantungan Anda. Perhatikan juga, ini hanya tersedia sebagai jar Java 9 sampai saya dapat mengetahui cara mempublikasikan beberapa target rilis dengan Gradle dan plugin Bintray.

jamespedwards42
sumber
0

Cara singkat dan mudah untuk mengonversi String menjadi notasi Heksadesimalnya adalah:

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
sumber
0

periksa solusi ini untuk String ke hex dan hex ke 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();
}

Outputnya sebagai berikut:

Clear Text = testString For; 0181; with.love

Teks Hex = 74657374537472696e6720466f723b303138313b776974682e6c6f7665

Teks yang Dekodekan = testString Untuk; 0181; with.love

Nitin Upadhyay
sumber