简体   繁体   English

如何将字节数组转换为用于将其转换为long的十六进制字符串?

[英]How to convert byte array to hex string which it is using for convert it to long?

I try to convert byte[] to long, but I got java.lang.NumberFormatException. 我尝试将byte []转换为long,但是却遇到了java.lang.NumberFormatException。

this is the byte array I wanna convert to long 这是我想转换为long的字节数组

byte[] data = new byte[]{(byte) 0xDB, (byte) 0xA7, 0x53, (byte) 0xF8, (byte) 0xA8, 0x0C, 0x66, 0x8};

Then I try to convert that data to hex string with this algorithm 然后我尝试使用此算法将该数据转换为十六进制字符串

public static String hexStringFromHexData(byte[] data){
        StringBuilder hexString = new StringBuilder();

        for (byte subData : data) {
            String temp = Integer.toHexString(subData & 0xFF);
            if (temp.length() == 1) {
                temp = "0" + temp;
            }
            hexString.append(temp);
        }

        return hexString.toString();
    }

So I got the hexstring like this "dba753f8a80c6608" 所以我得到了像这样的十六进制字符串“ dba753f8a80c6608”

with that hexstring I convert it to long like below 用那个十六进制字符串,我将其转换为如下长

String hexstring = "dba753f8a80c6608";
Long value = Long.parseLong(hexString.trim(), 16);

It throw NumberFormatException because the hexstring is exceed 7fffffffffffffff (Long.MAX_VALUE). 因为十六进制字符串超过7fffffffffffffff(Long.MAX_VALUE),所以将引发NumberFormatException。

The right hexstring have to be like this "DBA753F8A80C668" and with this hexstring is able to convert it to this long value 989231983928329832L without get exception. 正确的十六进制字符串必须像这样的“ DBA753F8A80C668”,并且使用此十六进制字符串可以将其转换为此长值989231983928329832L,而不会出现异常。

we can try convert this long value back to hex string 我们可以尝试将此long值转换回十六进制字符串

long value = 989231983928329832L
String hexString = Long.toHexString(value);

the we got the hexstring like this "DBA753F8A80C668" and if we convert it to byte array it will be same with byte array data like above. 我们得到了像“ DBA753F8A80C668”这样的十六进制字符串,如果我们将其转换为字节数组,它将与上述字节数组数据相同。

So how do I convert the byte[] data above to hex string like this "DBA753F8A80C668"? 那么,如何将上面的byte []数据转换为十六进制字符串,例如“ DBA753F8A80C668”?

Is it any other algorithm for convert byte[] data above and return correct long value like this 989231983928329832L? 是否有其他算法可以转换上面的byte []数据并返回正确的long值,例如989231983928329832L?

====================================================================== ================================================== ====================

simple step to reproduce: 重现的简单步骤:

  1. 989231983928329832 to convert it to byte[] data 989231983928329832转换为byte []数据

  2. convert byte[] data back to long value 989231983928329832L 将byte []数据转换回长值989231983928329832L

Your byte array is incorrect. 您的字节数组不正确。

    byte[] data = new byte[]{(byte) 0xDB, (byte) 0xA7, 0x53, (byte) 0xF8, (byte) 0xA8, 0x0C, 0x66, 0x8};
    long a = 989231983928329832L;
    byte[] bytes = ByteBuffer.allocate(8).putLong(a).array();
    for(int i = 0; i<8; i++){
        System.out.printf("%02x\t%02x\n", data[i], bytes[i]);
    }
    System.out.println(Long.parseLong(hexStringFromHexData(bytes), 16));

Which outputs. 哪个输出。

db 0d db 0d

a7 ba a7坝

53 75 53 75

f8 3f f8 3f

a8 8a a8 8a

0c 80 0分80

66 c6 66 c6

08 68 08 68

989231983928329832 989231983928329832

The first column is your byte array, the second column is the one created. 第一列是您的字节数组,第二列是创建的字节数组。 You can also see your string technique works with the correct byte array. 您还可以看到您的字符串技术适用于正确的字节数组。

The problem you are facing is due to the face that the long type in Java is signed, so the maximum absolute value you can have is indeed 0x7fffffffffffffff , smaller that the desired 0xDBA753F8A80C6608 . 您面临的问题是由于Java中的long类型是带符号的,因此您可以拥有的最大绝对值确实为0x7fffffffffffffff ,小于所需的0xDBA753F8A80C6608

You can solve the issue in several ways: 您可以通过多种方式解决此问题:

  • using BigInteger : BigInteger longValue = new BigInteger(1, data); 使用BigIntegerBigInteger longValue = new BigInteger(1, data);

  • if you can work with Java 8, you can use unsigned long , as pointed out in comments from @saka1029: long value = Long.parseUnsignedLong(hexString.trim(), 16); 如果您可以使用Java 8,则可以使用unsigned long ,如@ saka1029的注释中指出的: long value = Long.parseUnsignedLong(hexString.trim(), 16);

EDIT: after some research, I warn you that the output of the second method will appear negative if printed. 编辑:经过一些研究,我警告您,如果打印第二种方法的输出将显示为负数。 This is due to the fact that the long variable is still signed, and only some methods of the Long class treat is as unsigned. 这是由于long变量仍然是带符号的,并且Long类仅将某些方法视为无符号。 Here is the source I used 这是我使用的来源

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

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