当我使用 JavaMessageDigest
计算BigInteger
. 看起来有时哈希值有 256 位,但有时它只有 255 位。这是我用来测试 BigInteger 散列的代码:
@Test
public void testSHA256LengthConsistent() {
MessageDigest sha256 = null;
try {
sha256 = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
Assert.fail("NoSuchAlgorithmException. Can't construct the MessageDigest.");
}
BigInteger[] tests = {new BigInteger("15902493"), new BigInteger("5189087324092341824"), new BigInteger("7153293421609183203421127438153268")};
for(BigInteger testNum : tests) {
byte[] hash = sha256.digest(testNum.toByteArray());
Assert.assertEquals(32, hash.length); //256 bits is 32 bytes
BigInteger hashedInt = new BigInteger(1, hash);
Assert.assertEquals(256, hashedInt.bitLength());
}
}
(是的,我使用的是 JUnit 4)。此测试在第三个测试编号上失败,其中第二个断言失败并显示“预期为 256,但为 255”。
我将 BigIntegers 与字节数组转换的方式有问题吗?我可以为 Java 的 MessageDigest 找到的所有示例都使用它来散列字符串,而不是 BigInteger,所以我不知道是否有“标准”方式将 BigInteger 与 MessageDigest 一起使用。或者,这是 Java 处理 SHA-256 方式中的错误或边缘情况,并且 7153293421609183203421127438153268 (我随机生成的一个数字)会导致哈希中的一个错误?
顺便说一句,我已经尝试将哈希转换为负 BigInteger(使用new BigInteger(-1, hash)
)以查看符号位是否有问题,但我得到了完全相同的结果。