【问题标题】:Creating a ISO-8859-1 string from a HEX-string in Java, shifting bits从 Java 中的 HEX 字符串创建 ISO-8859-1 字符串,移位位
【发布时间】:2009-10-27 15:05:47
【问题描述】:

我正在尝试将 HEX 序列转换为以 ISO-8859-1、UTF-8 或 UTF-16BE 编码的字符串。也就是说,我有一个字符串,看起来像:"0422043504410442" 这代表字符:"Test" in UTF-16BE。

我用来在两种格式之间转换的代码是:

private static String hex2String(String hex, String encoding) throws UnsupportedEncodingException {
    char[] hexArray = hex.toCharArray();

    int length = hex.length() / 2;
    byte[] rawData = new byte[length];
    for(int i=0; i<length; i++){
        int high = Character.digit(hexArray[i*2], 16);
        int low = Character.digit(hexArray[i*2+1], 16);
        int value = (high << 4) | low;
        if( value > 127)
                value -= 256;
        rawData[i] = (byte) value;
    }
    return new String(rawData, encoding);
}

这对我来说似乎很好,但我仍然有两个问题:

  1. 有没有更简单的方法(最好没有位处理)来进行这种转换?
  2. 我该如何解释这行:int value = (high &lt;&lt; 4) | low;

我熟悉位处理的基础知识,但完全不了解 Java 语法。我相信第一部分将所有位向左移动 4 步。尽管其余的我不明白,为什么它在这种特定情况下会有所帮助。

对于我的问题中的任何混淆,我深表歉意,如果我需要澄清任何事情,请告诉我。 谢谢你。 //Abeansits

【问题讨论】:

    标签: java encoding hex byte-shifting


    【解决方案1】:

    有没有更简单的方法(最好没有位处理)来进行这种转换?

    我不知道 - 唯一的简化似乎是一次解析整个字节,而不是逐位解析(例如,使用 int value = Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);

    public static byte[] hexToBytes(final String hex) {
      final byte[] bytes = new byte[hex.length() / 2];
      for (int i = 0; i < bytes.length; i++) {
        bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
      }
      return bytes;
    }
    

    我该如何解释这一行:int value = (high

    查看此示例中的最后两位数字 (42):

    int high = 4; // binary 0100
    int low = 2; // binary 0010
    int value = (high << 4) | low;
    
    int value = (0100 << 4) | 0010; // shift 4 to left
    int value = 01000000 | 0010; // bitwise or
    int value = 01000010;
    int value = 66; // 01000010 == 0x42 == 66
    

    【讨论】:

      【解决方案2】:

      您可以将本例中的&lt;&lt;| 替换为*+,但我不建议这样做。

      表达式

      int value = (high << 4) | low;
      

      等价于

      int value = high * 16 + low;
      

      不需要减去 256 以获得介于 -128 和 127 之间的值。例如,简单地将 128 转换为一个字节将产生正确的结果。 int 128 的最低 8 位与 byte -128: 0x80 具有相同的模式。

      我会简单地写成:

      rawData[i] = (byte) ((high << 4) | low);
      

      【讨论】:

        【解决方案3】:

        有没有更简单的方法(最好 没有位处理)来做到这一点 转换?

        您可以在 Apache commons 中使用 Hex 类,但在内部,它会做同样的事情,也许会有细微差别。

        我该如何解释这行:int value = (high &lt;&lt; 4) | low;

        这会将两个十六进制数字(每个代表 4 位)组合成一个无符号 8 位值,存储为 int。接下来的两行将其转换为签名的 Java byte

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          • 2010-12-02
          • 1970-01-01
          • 2020-01-25
          • 2013-01-19
          • 2014-07-04
          相关资源
          最近更新 更多