33

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?

Anuj Balan
  • 7,629
  • 23
  • 58
  • 92
Dheeraj Joshi
  • 3,057
  • 8
  • 38
  • 55
  • 2
    Are you saying that `BigInteger.toString()` is *supposed* to output a leading zero? – Gabe Apr 23 '12 at 06:31
  • All i am asking is why toString is removing the leading 0. ? – Dheeraj Joshi Apr 23 '12 at 06:32
  • Yeah well and i get a negative vote as if it is not useful. Boohoo – Dheeraj Joshi Apr 23 '12 at 06:34
  • 3
    I don't understand what you're asking. How is `toString` supposed to know that you're expecting a leading 0? `BigInteger` stores just a number; it doesn't know how many leading zeroes you're expecting. – Gabe Apr 23 '12 at 06:35
  • 2
    Think of it another way: what would you expect from `new BigInteger("27").toString()`? How many leading zeros? – yshavit Apr 23 '12 at 07:30

5 Answers5

22

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);
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
13

String.format("%064X", new BigInteger(1, ByteArray);

where

  1. 0 - zero leading sign
  2. 64 - string length
  3. X - Uppercase
  4. ByteArray - The ByteArray on which you want to run this operation
ChiralCarbon
  • 347
  • 2
  • 11
Gorets
  • 2,434
  • 5
  • 27
  • 45
9

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).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
2

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

user1689394
  • 331
  • 1
  • 2
  • 9
  • I think Dheeraj was looking for reasons for the deleted zero. Not a way to get it back. Also, your code does not work the way you think it does. – allingeek Sep 27 '12 at 06:44
  • Sorry, you are right, but my code does work sending the correct md5 checksum to my server. – user1689394 Sep 27 '12 at 14:07
-2
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(PlainText.getBytes(),0,PlainText.length());
String M1=new BigInteger(1,m.digest()).toString(16);      
return M1;
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Aram
  • 1
  • Downvoted because your answer is not correctly formatted and it does not contain any explanations whatsoever. – Sync Feb 11 '18 at 17:42
  • I've fixed the formatting, but you still need to explain the code. Somebody [flagged your answer for deletion](https://stackoverflow.com/review/low-quality-posts/18790340), but [code-only answers are not low-quality](https://meta.stackoverflow.com/a/358757/1364007). Your answer appears to be an attempt to answer the question, so should not have been flagged. Does it deserve a downvote? Quite possibly - I can't comment on its correctness or usefulness - but I personally have not downvoted. – Wai Ha Lee Feb 11 '18 at 19:02