Java字符串十六进制到带重音符号的字符串ASCII

Java字符串十六进制到带重音符号的字符串ASCII,java,utf-8,hex,ascii,Java,Utf 8,Hex,Ascii,我有字符串hex=“6174656ec3a7c3a36f”我想得到字符串输出=“atenção”但在我的测试中,我只得到字符串输出=“aten???o” 我做错了什么 String hex = "6174656ec3a7c3a36f"; StringBuilder output = new StringBuilder(); for (int i = 0; i < hex.length(); i+=2) { String str = hex.substring(i, i+2); ou

我有字符串hex=“6174656ec3a7c3a36f”我想得到
字符串输出=“atenção”
但在我的测试中,我只得到
字符串输出=“aten???o”
我做错了什么

String hex = "6174656ec3a7c3a36f";
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));
} 

System.out.println(output); //here is the output "aten????o"
字符串hex=“6174656ec3a7c3a36f”; StringBuilder输出=新的StringBuilder(); 对于(int i=0;i
字符:每个字符以16位编码。我想你的字符串是“C”字符串。您必须知道字符编码器的名称和使用方法

导入java.nio.ByteBuffer;
导入java.nio.CharBuffer;
导入java.nio.charset.CharacterCodingException;
导入java.nio.charset.charset;
导入java.nio.charset.CharsetDecoder;
公共类Char8859\u 1解码器{
公共静态void main(字符串[]args)引发CharacterCodingException{
字符串hex=“6174656ec3a7c3a36f”;
int len=十六进制长度();
字节[]cStr=新字节[len/2];
对于(int i=0;i
ç和ã是16位字符,因此它们并不像您在解码例程中假设的那样由一个字节表示,而是由一个完整的字表示

我不会将每个字节转换为字符,而是将字节转换为java字节,然后使用字符串例程将字节数组解码为字符串,这样java就可以完成确定解码例程的枯燥任务

当然,java可能猜错了,所以根据@Aubin或@Martin Ellis给出的答案,您可能必须提前知道编码是什么

String hex = "6174656ec3a7c3a36f";                                  // AAA
ByteBuffer buff = ByteBuffer.allocate(hex.length()/2);
for (int i = 0; i < hex.length(); i+=2) {
    buff.put((byte)Integer.parseInt(hex.substring(i, i+2), 16));
}
buff.rewind();
Charset cs = Charset.forName("UTF-8");                              // BBB
CharBuffer cb = cs.decode(buff);                                    // BBB
System.out.println(cb.toString());                                  // CCC
字符串hex=“6174656ec3a7c3a36f”//AAA ByteBuffer buff=ByteBuffer.allocate(十六进制长度()/2); 对于(int i=0;i 其中打印:
atenção

    String hex = "6174656ec3a7c3a36f";
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (int i = 0; i < hex.length(); i += 2) {
      String str = hex.substring(i, i + 2);
      int byteVal = Integer.parseInt(str, 16);
      baos.write(byteVal);
    } 
    String s = new String(baos.toByteArray(), Charset.forName("UTF-8"));
基本上,十六进制字符串表示以UTF-8编码时表示字符串atenção中字符的字节的十六进制编码

要解码:

  • 首先必须从十六进制字符串转换为字节(AAA)
  • 然后从字节到字符(BBB)——这取决于编码,在您的例子中是UTF-8
  • 从字符到字符串的转换(CCC)

您的十六进制字符串似乎表示UTF-8字符串,而不是ISO-8859-1

我之所以这么说,是因为如果它是ISO-8859-1,那么每个字符有两个十六进制数字。十六进制字符串有18个字符,但预期输出只有7个字符。因此,十六进制字符串必须是可变宽度编码,而不是像ISO-8859-1那样每个字符一个字节

以下程序生成输出:
atenção

    String hex = "6174656ec3a7c3a36f";
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (int i = 0; i < hex.length(); i += 2) {
      String str = hex.substring(i, i + 2);
      int byteVal = Integer.parseInt(str, 16);
      baos.write(byteVal);
    } 
    String s = new String(baos.toByteArray(), Charset.forName("UTF-8"));
字符串hex=“6174656ec3a7c3a36f”; ByteArrayOutputStream bas=新的ByteArrayOutputStream(); 对于(int i=0;i 如果您将
UTF-8
更改为
ISO-8859-1
,您将看到:
atençÃo

可能的dup