BigInteger.toString方法正在删除前导0

时间:2012-04-23 06:24:48

标签: java tostring biginteger

我正在尝试使用MessageDigest生成MD5总和。 我有以下代码。

byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);

这不返回32个字符串,而是返回31个字符的字符串8611c0b0832bce5a19ceee626a403a7

预期字符串为08611c0b0832bce5a19ceee626a403a7

输出中缺少前导0。

我尝试了另一种方法

byte[] md5sum = digest.digest();
output = new String(Hex.encodeHex(md5sum));

输出符合预期。

我检查了doc并且Integer.toString根据它进行了转换

  

Character.forDigit提供的数字到字符映射是   使用,并在适当的情况下加上减号。

和在Character.forDigit方法

  

如果0< = digit<数字参数有效基数。

有人可以告诉我两种方法有何不同以及为什么删除前导?

5 个答案:

答案 0 :(得分:18)

我个人避免使用BigInteger将二进制数据转换为文本。这并不是它的真正含义,即使可以用于此目的。有大量代码可用于将byte[]转换为其十六进制表示 - 例如使用Apache Commons Codec或简单的单一方法:

private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
public static String toHex(byte[] data) {
    char[] chars = new char[data.length * 2];
    for (int i = 0; i < data.length; i++) {
        chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
        chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
    }
    return new String(chars);
}

答案 1 :(得分:8)

  

String.format(“%064X”,new BigInteger(1,   hmac.doFinal(message.getBytes())));

其中

  1. 0 - 零前导标志
  2. 64 - 字符串长度
  3. X - 大写

答案 2 :(得分:7)

根据BigInteger,它已被删除,因为前导零不重要。 27000000000027之间没有区别。

如果你想要一个特定的长度,你必须自己强迫它,例如:

output = ("00000000000000000000000000000000"+output).substring(output.length());

(尽管那是kludgy)。

答案 3 :(得分:2)

使用以下代码替换已删除的零:

MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(output.getBytes());
byte[] outDigest = digest.digest();
BigInteger outBigInt = new BigInteger(1,outDigest);
output = outBigInt.toString(16);
    while (output.length() < 32){
    output = "0"+output;
    }

循环将根据需要占据多个前导零

答案 4 :(得分:-2)

MessageDigest m=MessageDigest.getInstance("MD5");
m.update(PlainText.getBytes(),0,PlainText.length());
String M1=new BigInteger(1,m.digest()).toString(16);      
return M1;