자바에서 문자열을 16 진수로 변환


107

"testing123"과 같은 문자열을 자바에서 16 진수 형식으로 변환하려고합니다. 현재 BlueJ를 사용하고 있습니다.

그리고 그것을 다시 변환하는 것은 역방향을 제외하고는 동일한 것입니까?

java  string  hex 

제발 편집 표시하도록 질문을 지금까지 가지고있는 코드를 . 문제가있는 코드 의 개요 (하지만 가능한 최소한의 재현 가능한 예제 )를 포함해야합니다. 그러면 특정 문제에 대해 도움을 드릴 수 있습니다. How to Ask 도 읽어야 합니다.
Toby Speight

답변:


201

다음은 16 진수로 변환하는 간단한 방법입니다.

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

24
내가 본 3vilness의 가장 순수한 샘플에 +1 : BigInteger를 사용하여 바이트에서 변환 [] ...
Eduardo Costa

13
그것을 사랑하십시오! 루프와 비트 플 리핑이 없습니다. 나는 당신에게 0xFF를 upvotes :)주고 싶어
laher

5
40자를 보장하려면 0 채우기를 추가해야합니다. return String.format ( "% 040x", new BigInteger (arg.getBytes (/ * YOUR_CHARSET? * /)));
Ron

4
@Kaleb 가능한 경우 결과 문자열을 다시 변환 할 수 있는지 생각하십니까? 그렇다면 힌트를 좀 주실 수 있나요? 감사!
artaxerxe 2010

1
BigInteger(int,byte[])생성자 를 사용해야합니다 . 그렇지 않으면 첫 번째 바이트가 음수이면 음의 BigInteger를 얻습니다.
Joni

62

16 진수가 항상 40 자 길이인지 확인하려면 BigInteger가 양수 여야합니다.

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

1
이 방법은 실제로 올바른 방법입니다. 시도하십시오 byte[] data = { -1, 1 };-이 답변의 코드는 잘 작동하지만 17 개의 upvotes는 실패합니다.
hudolejev

1
-1문자열 에서 값이있는 바이트를 얻을 수 있습니까 (예제에서 요청한대로)?
Kaleb Pederson 2013 년

@KalebPederson 네. 별로 어렵지도 않습니다. . 당신의 인코딩하여 선택하면 지금하는 모든 문자의 최상위 비트 사용 (UTF-같은 말을 * 할), 당신이 부정적이 byte당신의 배열들.
기금 모니카의 소송

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
바퀴를 재발 명하고 싶지 않다면 흥미 롭습니다.
Federico Zancan 2012

3
@MelNicholson Hex에는 byte []로 이동하는 decodeHex 함수가 있습니다. 임의의 HEX 문자열이 인코딩에서 문자열로 변환 될 수 있다는 보장이 없기 때문에이를 사용해야합니다.
BxlSofty 2014 년

18

16 진수로 인코딩하는 숫자는 UTF-8과 같은 문자의 일부 인코딩을 나타내야합니다. 따라서 먼저 문자열을 해당 인코딩의 문자열을 나타내는 byte []로 변환 한 다음 각 바이트를 16 진수로 변환합니다.

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

이것은 흥미로운 솔루션이며 데이터의 디지털 표현의 핵심을 공격합니다. 당신이하고있는 일과 솔루션의 "매직 넘버"가 무엇을 나타내는 지 설명해 주시겠습니까? 초보자는 >>> 연산자가 무엇을 의미하는지, 왜 우리가 0xF0의 마스크와 함께 bitwise-and &를 사용하는지, 왜 chars 배열의 크기가 [2 * buf.length]인지 모를 수 있습니다.
Boris

16

사용 DatatypeConverter.printHexBinary():

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

    return DatatypeConverter.printHexBinary(myBytes);
}

사용 예 :

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

인쇄물:

48656C6C6F20537461636B4F766572666C6F77

참고 : Java 9API가 기본적으로 포함되어 있지 않기 때문에 이로 인해 약간의 추가 문제가 발생합니다 . 참고 로이 GitHub 문제 를 참조하십시오 .


11

여기에 다른 해결책

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
좋지만 format("%02x")format ()은 항상 2 문자를 사용합니다. ASCII가 두 자리 16 진수이지만 A = 0x65
mike jones

8

String.getBytes () 기반의 모든 답변 에는 Charset에 따라 문자열을 인코딩 하는 것이 포함됩니다 . 문자열을 구성 하는 2 바이트 문자 의 16 진수 값을 반드시 얻을 필요는 없습니다 . 실제로 원하는 것이 16 진 뷰어와 동일하다면 문자에 직접 액세스해야합니다. 유니 코드 문제를 디버깅하기 위해 코드에서 사용하는 함수는 다음과 같습니다.

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

그러면 stringToHex ( "testing123")가 다음을 제공합니다.

0074 0065 0073 0074 0069 006e 0067 0031 0032 0033

원하는 것이 유니 코드의 특정 표현 인 UTF-16 인 Java 문자의 내부 표현을 보는 것이라면 괜찮습니다.
Jonathan Rosenne 2018 년

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

hexString이 시점에서 반환 할 수 있습니다. 선행 null-chars가 제거되고 첫 번째 바이트가 16보다 작 으면 결과 길이가 홀수입니다. 이러한 경우를 처리해야하는 경우 추가 코드를 추가 할 수 있습니다. 0으로 채우려면 :

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

5

16 진수의 정수 값을 얻으려면

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

5

16 진수 코드의 문자와 문자의 16 진수 코드를 변환합니다.

        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

다음과 같은 것을 제안 str합니다. 입력 문자열은 어디에 있습니까 ?

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

수정 해 주셔서 감사합니다, Software Monkey. 답을 썼을 때 꽤 피곤했고 'raw [i] <= 9'에 대한 테스트로는 분명히 불충분합니다.
rodion

1
이것은 정말 잘 작동합니다. 생성 된 16 진수를 다시 문자열로 되돌릴 수있는 방법이 있습니까?

1
여기서 str은 어디에 있습니까?
Viswanath Lekshmanan

3

먼저 getBytes () 함수를 사용하여 바이트로 변환 한 다음 다음을 사용하여 16 진수로 변환합니다.

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

다른 방법 (16 진수에서 문자열로)으로 이동하려면 다음을 사용할 수 있습니다.

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

문자열을 16 진수로 변환 :

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

확실히 이것은 쉬운 방법입니다.


이것은 해결책이 아닙니다. 질문은 임의의 문자열 내용의 16 진수 표현을 얻는 방법을 묻는 것이며, 구체적으로 "testing123" 을 예로 제공했습니다.
skomisa

1

여러 사람을 사용하면 여러 스레드에서 도움이됩니다.

나는 이것이 대답되었다는 것을 알고 있지만 동일한 상황에있는 다른 사람들에게 완전한 인코딩 및 디코딩 방법을 제공하고 싶습니다.

다음은 내 인코딩 및 디코딩 방법입니다 ..

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

좋은! 13 행에서만 ">>>"는 ">>"이어야합니다
spikeyang

0

훨씬 낫다:

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

다음은 다양한 접근 방식과 라이브러리를 비교 하는 몇 가지 벤치 마크 입니다. Guava는 디코딩에서 Apache Commons Codec을 능가합니다. Commons Codec은 인코딩에서 Guava를 능가합니다. 그리고 JHex는 디코딩과 인코딩 모두를 능가합니다.

JHex 예

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

모든 것이 JHex 용 단일 클래스 파일에 있습니다 . 종속성 트리에 아직 다른 라이브러리를 원하지 않는 경우 자유롭게 복사하여 붙여 넣으십시오. 또한 Gradle 및 Bintray 플러그인을 사용하여 여러 릴리스 대상을 게시하는 방법을 알아낼 때까지 Java 9 jar로만 사용할 수 있습니다.


0

문자열을 16 진수 표기법으로 변환하는 간단하고 편리한 방법은 다음과 같습니다.

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

이 솔루션에서 문자열을 16 진수로, 16 진수를 문자열로 확인하십시오.

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

다음과 같이 출력합니다.

일반 텍스트 = testString For; 0181; with.love

16 진수 텍스트 = 74657374537472696e6720466f723b303138313b776974682e6c6f7665

디코딩 된 텍스트 = testString For; 0181; with.love

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.