Java的SHA-256有时会返回255位

Edw*_*ard 1 java hash biginteger sha

当我使用Java MessageDigest来计算a的SHA-256哈希时,我遇到了一些奇怪的行为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());
    }
}
Run Code Online (Sandbox Code Playgroud)

(是的,我正在使用JUnit 4).此测试在第三个测试编号上失败,其中第二个断言失败并显示"预期256但是为255".

我将BigIntegers转换为字节数组的方式有什么问题吗?我可以为Java的MessageDigest找到的所有示例都使用它来散列字符串,而不是BigIntegers,所以我不知道是否有一种"标准"方式将BigIntegers与MessageDigest一起使用.或者,这是Java执行SHA-256的方式的错误或边缘情况,并且有一些东西与7153293421609183203421127438153268(我随机生成的数字)导致散列中的一个一个错误?

顺便说一句,我已经尝试将哈希转换为负BigInteger(使用new BigInteger(-1, hash))以查看它是否与符号位有问题,但我得到完全相同的结果.

Pet*_*rey 7

前导零被忽略

byte[] bytes = {0x0, 0x1};
System.out.println(new BigInteger(1, bytes).bitLength());
Run Code Online (Sandbox Code Playgroud)

版画

1
Run Code Online (Sandbox Code Playgroud)

不像你期望的那样16岁.


我应该读过Javadoc,因为它在BigInteger.bitLength()中声明

此BigInteger的最小二进制补码表示中的位数,不包括符号位.

  • 是的,我建议删除此测试.不要测试平台.如果你不相信哈希算法给你正确的位数,你怎么能相信它给你正确的哈希?你必须停在某个地方,否则你会发疯. (3认同)