我正在尝试将HEX序列转换为以ISO-8859-1,UTF-8或UTF-16BE编码的字符串。也就是说,我有一个字符串看起来像:"0422043504410442"这代表字符:"Test"在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 << 4) | low;
  3. 我熟悉位处理的基础知识,但完全不熟悉Java语法。我相信第一部分将所有位向左移动4步。虽然其余的我不明白,为什么它会在这种情况下有所帮助。

    我为我的问题中的任何混淆道歉,如果我要澄清任何事情,请告诉我。 谢谢。 // Abeansits

有帮助吗?

解决方案

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

没有我会知道 - 唯一的简化似乎是一次解析整个字节而不是逐位解析(例如使用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 <!> lt; <!> lt; 4)|低;吗

查看此示例中的最后两位数字(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

其他提示

在这种情况下,你可以用<<|替换*+,但我不推荐它。

表达式

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);
scroll top