BigInteger.toString method is deleting leading 0

2019-01-14 06:37发布

I am trying to generate MD5 sum using MessageDigest. And i am having following code.

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

This returns not 32 character string but a 31 character string 8611c0b0832bce5a19ceee626a403a7

Expected String is 08611c0b0832bce5a19ceee626a403a7

Leading 0 is missing in the output.

I tried the other method

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

And the output is as expected.

I checked the doc and Integer.toString does the conversion according to it

The digit-to-character mapping provided by Character.forDigit is used, and a minus sign is prepended if appropriate.

and in Character.forDigit methos

The digit argument is valid if 0 <=digit < radix.

Can some one tell me how two methods are different and why leading 0 is deleted?

5条回答
霸刀☆藐视天下
2楼-- · 2019-01-14 06:57

It's deleted because the leading zero is not significant, according to BigInteger. There is no difference between 27 and 000000000027.

If you want a specific length, you'll have to force it yourself, with something like:

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

(kludgy though that is).

查看更多
爷、活的狠高调
3楼-- · 2019-01-14 07:05

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

where

  1. 0 - zero leading sign
  2. 64 - string length
  3. X - Uppercase
查看更多
Deceive 欺骗
4楼-- · 2019-01-14 07:07

I would personally avoid using BigInteger to convert binary data to text. That's not really what it's there for, even if it can be used for that. There's loads of code available to convert a byte[] to its hex representation - e.g. using Apache Commons Codec or a simple single method:

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);
}
查看更多
狗以群分
5楼-- · 2019-01-14 07:08

The deleted zero is replaced using this code:

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;
    }

loop will account for as many leading zeros as needed

查看更多
爷的心禁止访问
6楼-- · 2019-01-14 07:12
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(PlainText.getBytes(),0,PlainText.length());
String M1=new BigInteger(1,m.digest()).toString(16);      
return M1;
查看更多
登录 后发表回答