Java - 将无符号十六进制字符串解析为有符号长整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5723579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:29:15  来源:igfitidea点击:

Java - parse and unsigned hex string into a signed long

javahexlong-integer

提问by Peter

I have a bunch of hex strings, one of them, for example is:

我有一堆十六进制字符串,例如其中一个是:

  d1bc4f7154ac9edb

which is the hex value of "-3333702275990511909". This is the same hex you get if you do Long.toHexString("d1bc4f7154ac9edb");

这是“-3333702275990511909”的十六进制值。如果你执行 Long.toHexString("d1bc4f7154ac9edb"); 这与你得到的十六进制相同。

For now, let's just assume I only have access to the hex string values and that is it. Doing this:

现在,让我们假设我只能访问十六进制字符串值,就是这样。这样做:

  Long.parseLong(hexstring, 16);

Doesn't work because it converts it to a different value that is too large for a Long. Is there away to convert these unsigned hex values into signed longs?

不起作用,因为它将其转换为对 Long 来说太大的不同值。是否可以将这些无符号十六进制值转换为有符号长整型?

Thanks!

谢谢!

回答by WhiteFang34

You can use BigIntegerto parse it and get back a long:

您可以使用BigInteger来解析它并返回一个long

long value = new BigInteger("d1bc4f7154ac9edb", 16).longValue();
System.out.println(value); // this outputs -3333702275990511909

回答by Knut Forkalsrud

You may split it in half and read 32 bits at a time. Then use shift-left by 32 and a logical or to get it back into a single long.

您可以将其分成两半并一次读取 32 位。然后使用 shift-left by 32 和逻辑 or 将其恢复为单个 long。

回答by Olathe

The method below has the benefit of not creating another BigIntegerobject every time you need to do this.

下面的方法的好处是不需要BigInteger每次都创建另一个对象。

public class Test {
  /**
   * Returns a {@code long} containing the least-significant 64 bits of the unsigned hexadecimal input.
   * 
   * @param  valueInUnsignedHex     a {@link String} containing the value in unsigned hexadecimal notation
   * @return                        a {@code long} containing the least-significant 64 bits of the value
   * @throws NumberFormatException  if the input {@link String} is empty or contains any nonhexadecimal characters
   */
  public static final long fromUnsignedHex(final String valueInUnsignedHex) {
    long value = 0;

    final int hexLength = valueInUnsignedHex.length();
    if (hexLength == 0) throw new NumberFormatException("For input string: \"\"");
    for (int i = Math.max(0, hexLength - 16); i < hexLength; i++) {
      final char ch = valueInUnsignedHex.charAt(i);

      if      (ch >= '0' && ch <= '9') value = (value << 4) | (ch - '0'         );
      else if (ch >= 'A' && ch <= 'F') value = (value << 4) | (ch - ('A' - 0xaL));
      else if (ch >= 'a' && ch <= 'f') value = (value << 4) | (ch - ('a' - 0xaL));
      else                             throw new NumberFormatException("For input string: \"" + valueInUnsignedHex + "\"");
    }

    return value;
  }

  public static void main(String[] args) {
    System.out.println(fromUnsignedHex("d1bc4f7154ac9edb"));
  }
}

This produces

这产生

-3333702275990511909

回答by Scott Carey

The prior answers are overly complex or out of date.

先前的答案过于复杂或过时。

Long.parseUnsignedLong(hexstring, 16)

Long.parseUnsignedLong(hexstring, 16)