2

I am trying to generate sha1 of a string by referring to the example in this link - http://www.sha1-online.com/sha1-java/

public class HashTextTest {

/**
 * @param args
 * @throws NoSuchAlgorithmException 
 */
public static void main(String[] args) throws NoSuchAlgorithmException {
    System.out.println(sha1("test string to sha1"));
}

static String sha1(String input) throws NoSuchAlgorithmException {
    MessageDigest mDigest = MessageDigest.getInstance("SHA1");
    byte[] result = mDigest.digest(input.getBytes());
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < result.length; i++) {
        sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString(); 

   }
}

I dont want to have this messy line of code from string buffer - sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));.

Is there any alternate way to doing this?

Buddhima Gamlath
  • 2,318
  • 1
  • 16
  • 26
rickygrimes
  • 2,637
  • 9
  • 46
  • 69
  • 2
    Nothing to do with SHA1. Instead you're simply looking how to turn a `byte[]` into a *textual hex representation* (or some variant with the odd `+ 0x100` ..). – user2864740 Jan 03 '14 at 06:06
  • Yes, see this answer: http://stackoverflow.com/a/4895922/495796 – Robin Green Jan 03 '14 at 06:07
  • @user2864740 - Agree. It has nothing to do with sha1 string. In the code, I am basically looking for a more graceful way of converting Byte Array to Hex String. – rickygrimes Jan 03 '14 at 06:09
  • A few variants, one is very similar (but in a tidy function), one using EncodingTool and one with BigInteger. I think there is also an Apache Commons approach floating about. YMMV: http://stackoverflow.com/questions/11822402/how-do-i-convert-a-large-string-into-hex-and-then-into-byte?rq=1 and snother similar post http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java?rq=1 (with some different implementations) – user2864740 Jan 03 '14 at 06:09
  • Thank you all so much. Let me take a look at these posts. – rickygrimes Jan 03 '14 at 06:11
  • @Hafthor are you sure? – Dawood ibn Kareem Jan 03 '14 at 06:50
  • @DavidWallace sigh... java has signed bytes. This should work sb.append(Integer.toString(512+result[i],16).substring(1); // deleted old comment to prevent its use – Hafthor Jan 03 '14 at 06:58

1 Answers1

2

What you need here is to format a byte as two hex digits.

sb.append(String.format("%02x", result[i])); would do it.

If you need uppercase hex digits, use

sb.append(String.format("%02X", result[i]));


Additionaly if you do not mind spaces between encoded bytes, you can use

new sun.misc.HexDumpEncoder().encode(result).substring(6);

to encode the whole byte[] at once.

Buddhima Gamlath
  • 2,318
  • 1
  • 16
  • 26
  • It should be pointed out that using any sun.* class is a bad idea. Those classes are private to the Java implementation, and may change or even disappear in any future release of Java, even a minor update. – VGR Jan 04 '14 at 03:36