java - 为什么十六进制表示 89 在 Java 中使用 toString 后不能正确打印为 ‰?

标签 java string hex tostring xor

执行异或并将十六进制转换为字符串后,我希望十六进制值“89”显示为“‰”,但 Eclipse 显示为“?”。调试时,字符实际上是空白的。为什么?

  1. 我将字符串“r”转换为十六进制 =>“72”。
  2. 然后我将“72”与“FB”(û) => “89”异或。
  3. 然后我使用这个函数将“89”转换为字符串:

    public static String HexToString(String hex){
      StringBuilder sb = new StringBuilder();
      StringBuilder temp = new StringBuilder();
    
      for( int i=0; i<hex.length()-1; i+=2 ){
    
          //grab the hex in pairs
          String output = hex.substring(i, (i + 2));
    
          //convert hex to decimal
          int decimal = Integer.parseInt(output, 16);
    
          //convert the decimal to character
          sb.append((char)decimal);
    
          temp.append(decimal);
      }
      System.out.println("Decimal : " + temp.toString());
    
      return sb.toString();
      }
    

将结果打印到控制台后,我看到“?”代替 ”‰”。怎么了?

编辑: 这是显示十进制值和 (char)decimal 调试值的屏幕截图。 (char)decimal

最佳答案

首先,Java 在内部完全是 Unicode(尽管不是最新版本的 Unicode,原因很复杂,在这里并不重要)。 89 十六进制将是 \u0089,它是一个扩展控制字符(带对齐的字符列表),就像在字符集中 ISO-8859-1 中一样;对于前 256 个字符,Unicode 与 ISO-8859-1 完全相同。根据您的描述,我猜您使用的是 Windows 并且配置了使用 CP1252 character set 的东西。 , 它将 89 hex 解释为 但从 Unicode 的转换是通过映射到等效字符来完成的(在打印到控制台期间),而不仅仅是将字节输出;因为 C1 控制字符在 CP1252 中没有等效字符,所以它最终成为替换字符(在本例中为问号)。

这个故事的寓意是字符不是字节,在这个领域工作时您需要非常小心字符集。 (或者你应该使用一个完整的 Unicode 系统,这些问题在很大程度上消失了,但代价是字符是比以前复杂得多的实体。)

关于java - 为什么十六进制表示 89 在 Java 中使用 toString 后不能正确打印为 ‰?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10503790/

相关文章:

php - 在 PHP 中用 == 比较不同的字符串返回 true

java - 如何在没有正则表达式的情况下拆分字符串

hex - 如何在 Scratch 中快速从十六进制转换为十进制?

java - 执行程序服务出现问题,列表大小始终为零?

java - 如果对象被移动到另一个包或重命名,我该如何反序列化?

java - 如何计算java中相同(PALINDROME)的单词数

java - OSGi:如何找出哪些 bundle 正在使用我导出的服务?

python - 找出段落中出现的单词

c++ - 这是什么 (0x01000000) 以及如何存储它?

perl - 是否有将 c99 十六进制浮点符号转换为常规符号的 Perl 模块?