简体   繁体   English

Java - 将解析和无符号十六进制字符串转换为带符号的long

[英]Java - parse and unsigned hex string into a signed long

I have a bunch of hex strings, one of them, for example is: 我有一堆十六进制字符串,其中一个,例如:

  d1bc4f7154ac9edb

which is the hex value of "-3333702275990511909". 这是十六进制值“-3333702275990511909”。 This is the same hex you get if you do Long.toHexString("d1bc4f7154ac9edb"); 如果你做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. 不起作用,因为它将它转换为对Long来说太大的不同值。 Is there away to convert these unsigned hex values into signed longs? 是否可以将这些无符号十六进制值转换为有符号长整数?

Thanks! 谢谢!

You can use BigInteger to parse it and get back a long : 你可以使用BigInteger来解析它并获得一个long

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

You may split it in half and read 32 bits at a time. 您可以将其拆分为一半,一次读取32位。 Then use shift-left by 32 and a logical or to get it back into a single long. 然后使用shift-left by 32和逻辑或将其恢复为单个long。

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

Long.parseUnsignedLong(hexstring, 16)

The method below has the benefit of not creating another BigInteger object 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM