填充到十六进制的目的是什么?

时间:2014-09-06 05:31:29

标签: java encryption hex

您好我读了this post有关如何对密码实施salt和哈希的问题,而且我被困在上面指定的网站下面的指定代码中。

private static String toHex(byte[] array)
{
    BigInteger bi = new BigInteger(1, array);
    String hex = bi.toString(16);
    int paddingLength = (array.length * 2) - hex.length();
    if(paddingLength > 0)
        return String.format("%0" + paddingLength + "d", 0) + hex;
    else
        return hex;
}

我的问题是,如果结果paddingLength大于零,他们为什么要计算paddingLength并将其实施到十六进制?

2 个答案:

答案 0 :(得分:2)

BigInteger(byte[])将字节数组解释为二进制补码值;这意味着它有一个N长度数组的2 ^(8 * N)个可能值(因为每个字节包含8位)。

同时,长度为M的十六进制字符串有16 ^ M个可能的值(因为每个字符编码16个值中的一个)。

作者想要byte[]String之间的一对一映射:给定一个字符串,您应该能够准确地确定它来自byte[]。为此,我们必须确保字符串可以编码与byte[]完全相同的值。从上面插入数字,我们得到:

(# values for an N-length byte[]) == (# values for an M-length String)
2^(8*N)                           == 16^M

让我们用N来解决M.第一步是重写那个右手边。如果你还记得你的exponent power rules,那么^(b * c)==(a ^ b)^ c。让我们得到右边的指数的基数为2:

                                  == (2^4)^M
                                  == 2^(4*M)

所以我们有2 ^(8 * N)== 2 ^(4 * M)。如果2 ^ k == 2 ^ j,则表示k == j。所以,8 * N == 4 * M.将两边除以4得到M = 2N。

要将它绑定在一起,请记住N是字节数组的长度,M是十六进制字符串的长度。我们刚刚发现,为了实现一对一映射,M = 2N - 换句话说,十六进制字符串应该是字节数组的两倍。

填充确保了。

答案 1 :(得分:1)

因为他们希望数组中的所有字节都以十六进制字符串表示,即使它们是前导零字节。

虽然这不是编写toHex方法最明显的方法。

我发现这样的东西更加清晰:

private static String toHex(byte[] array) {
    StringBuilder s = new StringBuilder();
    for (byte b : array) {
        s.append(String.format("%02x", b));
    }
    return s.toString();
}