您好我读了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
并将其实施到十六进制?
答案 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();
}