BigInteger 异或的大小

我的程序生成两个随机 BigInteger,bitLength 为 255。然后它生成这两个 BigInteger 的异或。


问题是:由于大整数的大小是最小的,如果第一个位是 0,这个异或的大小可以小于 255。我需要它是 32 字节,所以在 248 和 256 位之间。


这是我的代码:


public class test {


    public static void main(String[] args) throws Exception {

        SecureRandom random;

        BigInteger randomBigInteger1;

        byte[] randomBytes;

        do {

            random = new SecureRandom();

            randomBytes = new byte[32];

            random.nextBytes(randomBytes);

            randomBigInteger1 = new BigInteger(randomBytes);

        }while(randomBigInteger1.bitLength() < 255);


        BigInteger randomBigInteger2;

        do {

            random = new SecureRandom();

            randomBytes = new byte[32];

            random.nextBytes(randomBytes);

            randomBigInteger2 = new BigInteger(randomBytes);

        }while(randomBigInteger2.bitLength() < 255);


        BigInteger finalXor = randomBigInteger1.xor(randomBigInteger2);

        System.out.println(finalXor.bitLength());


        byte[] key = finalXor.toByteArray();

        System.out.println(key.length);

    }


}

问题是:即使 finalXor 小于 248 位,如何确保密钥始终为 32 字节?(我想我可以用位 0 填充,但我不知道如何。)


示例:让我们说我的 BigIntegers 是:


1111011010101101........11011100011


1111011001100111.................01110011010


那么 finalXor 将是:


0000000011001010................10101111001


高 8 位全为空,因此最终异或长度仅为 255-8 = 247 位长。当我制作 byte[] 键时,它将是 31 字节而不是 32。我需要它是 32 字节。并且仍然是好的异或。


这就是为什么我说我认为我应该做一个填充,其中所有“缺少的高位”都是 0,但我不知道该怎么做。


心有法竹
浏览 148回答 2
2回答

隔江千里

ISTM是避免BigInteger和异或直接在字节数组可以同时解决几个你的问题。在必要的地方有填充,你总是得到一个 32 字节的数组。如果您确保顶部字节(由于大端字节序在索引 0 处)不相同,您将始终拥有 248-255 位值。如果需要小端字节序,则索引 31 处的字节不得为 0 且不同。我假设了 big-endian,因为这也是 BigInteger 在您的原始代码中返回的内容。public class test&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; public static void main(String[] args) throws Exception&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SecureRandom random = new SecureRandom();&nbsp; &nbsp; &nbsp; &nbsp; // make "left" operand&nbsp; &nbsp; &nbsp; &nbsp; byte[] randomBytesLeft = new bytes[32];&nbsp; &nbsp; &nbsp; &nbsp; random.nextBytes(randomBytesLeft);&nbsp; &nbsp; &nbsp; &nbsp; // make "right" operand&nbsp; &nbsp; &nbsp; &nbsp; byte[] randomBytesRight = new byte[32];&nbsp; &nbsp; &nbsp; &nbsp; do&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; random.nextBytes(randomBytesRight);&nbsp; &nbsp; &nbsp; &nbsp; } while (randomBytesRight[0] == randomBytesLeft[0]); // or [31] for little-endian&nbsp; &nbsp; &nbsp; &nbsp; // "xor" both operands&nbsp; &nbsp; &nbsp; &nbsp; byte[] key = new byte[32];&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 32; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; key[i] = randomBytesLeft[i] ^ randomBytesRight[i];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // if you really need a BigInteger:&nbsp; &nbsp; &nbsp; &nbsp; // BigInteger finalXor = new BigInteger(key);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(key.length);&nbsp; &nbsp; }}FWIW,在我看来,您可以完全省略xoring,只需执行以下操作:&nbsp; &nbsp; &nbsp; &nbsp; byte[] key = new byte[32];&nbsp; &nbsp; &nbsp; &nbsp; do&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; random.nextBytes(key);&nbsp; &nbsp; &nbsp; &nbsp; } while (key[0] == 0); // or key[31] for little-endian那可能同样好,更简单。

狐的传说

填充 0 是一种选择,我找到了一种方法:if(key.length != 32) {&nbsp; &nbsp; byte[] finalKey= new byte[32];&nbsp; &nbsp; byte a = Byte.parseByte("00000000", 2);&nbsp; &nbsp; for(int i =0; i<key.length; i++)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; finalKey[i] = key[i];&nbsp; &nbsp; for (int i = key.length ; i<32 ; i++)&nbsp; &nbsp; &nbsp; &nbsp; finalKey[i] = a;&nbsp; &nbsp; key = finalKey;}它需要一个循环和另一个字节数组,因为出于某种原因,key[31] 抛出了一个 ArrayOutOfBound 异常,但它有效……如果有人可以改进它,请随时这样做。编辑: OldCurmudgeon 的更好解决方案:key = Arrays.copyOf(key, 32);它会自动用 0 填充高位。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java