Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将十六进制转换为BigInteger_Java - Fatal编程技术网

Java 将十六进制转换为BigInteger

Java 将十六进制转换为BigInteger,java,Java,我正在尝试将十六进制转换为大整数。基本上我有32个字符=16个字节,所以我希望biginger也有16个字节,但在某些情况下,即十六进制以99开头。。它用0生成额外的字节。我正在使用 new BigInteger(hex, 16) 超过127的字节值不能用java的字节>代码表示,因为它们被签名了(他们可以,但是java会把它们看作负数)。 当biginger将值转换为字节数组时,它将在前面添加一个0字节,以区分正值和负值 这导致128将变成[0][-128],而-128将变成[-128] 如

我正在尝试将十六进制转换为大整数。基本上我有32个字符=16个字节,所以我希望
biginger
也有16个字节,但在某些情况下,即十六进制以99开头。。它用0生成额外的字节。我正在使用

new BigInteger(hex, 16)

<如何避免第十七字节?

< p>超过127的字节值不能用java的字节>代码表示,因为它们被签名了(他们可以,但是java会把它们看作负数)。 当
biginger
将值转换为字节数组时,它将在前面添加一个0字节,以区分正值和负值

这导致
128
将变成
[0][-128]
,而
-128
将变成
[-128]

如果要将生成的字节存储为无符号128位值,只需切掉数组的第一个元素,例如,
byte[]sanitizedBytes=Arrays.copyOfRange(myBytes,1,16)

来自:

不可变的任意精度整数。所有操作的行为都像 大整数用二的补码表示法(类似于Java的 基元整数类型)

以及:

转换指定格式中BigInteger的字符串表示形式 将基数转换为一个大整数。字符串表示法由 可选的减号或加号,后跟一个或多个序列 指定基数中的数字。字符到数字的映射是 由Character.digit提供。字符串不能包含任何无关的内容 字符(例如空格)

这意味着,如果您使用
new biginger(“9900000000000000000000000000000”,16)
调用它,您将得到一个biginger,它保存该值(它是一个正值),就像它是用两位补符号表示的一样。2的补码中的正值不适合16个字节,因此最终结果当然是17个字节长

如果使用介于(包括两个)之间的值调用BigInteger,则保证获得最大值为16字节的BigInteger:


任何高于第一个或低于最后一个的值都将导致超过16个字节。

第一个字节不能以
1
位开头,因为这意味着一个负数。它们通过在数组的开头添加额外的零字节来防止这种情况。此函数将检查并切掉该字节:

public static byte[] signedToUnsignedBytes(byte[] myBytes) {
    return myBytes.length > 1 && myBytes[0] == 0
        ? Arrays.copyOfRange(myBytes, 1, myBytes.length)
        : myBytes;
}

似乎您使用
biginger
的唯一目的是将固定长度的十六进制字符串转换为
byte[]
数组。这可以通过另一种方式完成,例如,使用
ByteBuffer
class:

static byte[] toByteArray(String s) {
    ByteBuffer bb = ByteBuffer.allocate(16);
    bb.asIntBuffer().put((int) Long.parseLong(s.substring(0, 8), 16))
                    .put((int) Long.parseLong(s.substring(8, 16), 16))
                    .put((int) Long.parseLong(s.substring(16, 24), 16))
                    .put((int) Long.parseLong(s.substring(24), 16));
    return bb.array();
}
或者在Java-8中使用
Long.parseUnsignedLong()
更简单一些:

这样,您就不必关心死角情况(即使对于
“000…000”
字符串,您也将始终获得16个字节),并且可能会有更少的堆分配。示例用法:

System.out.println(Arrays.toString(toByteArray("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("80000000000000000000000000000000")));
// [-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
System.out.println(Arrays.toString(toByteArray("123FFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [18, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("007FFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [0, 127, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("00000000000000000000000000000001")));
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

我发现很难准确地理解问题所在。如果您发布一个简短但完整的程序来演示问题,即输入、实际输出和预期输出,那么会更容易帮助您。由于Java的符号性,任何以
80
或更高开头的值在执行
toByteArray()
时都会产生一个“额外”字节,所以没有别的办法,只有这个额外的0(实际上,如果十六进制以
000
007
开头,则字节数也可能少于16。如果是某种哈希函数,则有
1/512
的可能。也可以测试这种情况。
static byte[] toByteArray8(String s) {
    ByteBuffer bb = ByteBuffer.allocate(16);
    bb.asLongBuffer().put(Long.parseUnsignedLong(s.substring(0, 16), 16))
                     .put(Long.parseUnsignedLong(s.substring(16), 16));
    return bb.array();
}
System.out.println(Arrays.toString(toByteArray("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("80000000000000000000000000000000")));
// [-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
System.out.println(Arrays.toString(toByteArray("123FFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [18, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("007FFFFFFFFFFFFFFFFFFFFFFFFFFFFF")));
// [0, 127, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
System.out.println(Arrays.toString(toByteArray("00000000000000000000000000000001")));
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]