56

I am working on an Android app and have a couple strings that I would like to encrypt before sending to a database. I'd like something that's secure, easy to implement, will generate the same thing every time it's passed the same data, and preferably will result in a string that stays a constant length no matter how large the string being passed to it is. Maybe I'm looking for a hash.

3
  • 1
    A hash is unidirectional, if you want to be able to decrypt data you can't store with a constant length IMHO Commented Oct 14, 2010 at 14:41
  • 2
    I know. It's for validation and I just need to be able to compare one value to another, won't need to "undo" it. I know I didn't say whether I planned to decrypt, so thanks for responding. Commented Oct 14, 2010 at 14:48
  • 1
    No offense but the title of your question is misleading Commented Sep 23, 2015 at 8:12

12 Answers 12

97

This snippet calculate md5 for any given string

public String md5(String s) { try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); for (int i=0; i<messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } 

Source: http://www.androidsnippets.com/snippets/52/index.html

Hope this is useful for you

Sign up to request clarification or add additional context in comments.

9 Comments

MD5, afaik, isn't considered reversible. Typically you'd hash something with it, commonly a password or something similar, and then to verify the password you'll run the same encryption and compare the results to what's stored.
This code does not work properly. Some "0" characters becomes missing in the generated string. I don't know why, but that's the case.
There's a special condition when this code fails. When the first of two digit Hex number is zero. This code is better: stackoverflow.com/a/6565597/221135
this will cause problem i had tried diffrence is only 0--> when i am conver using this function then it give me result(String is: a) result: cc175b9c0f1b6a831c399e269772661 0cc175b9c0f1b6a831c399e269772661
Agree with @SertalpBilal, correct answer is here stackoverflow.com/a/4846511/1092591
|
65

That function above from (http://www.androidsnippets.org/snippets/52/index.html) is flawed. If one of the digits in the messageDigest is not a two character hex value (i.e. 0x09), it doesn't work properly because it doesn't pad with a 0. If you search around you'll find that function and complaints about it not working. Here a better one found in the comment section of this page, which I slightly modified:

public static String md5(String s) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); digest.update(s.getBytes(Charset.forName("US-ASCII")),0,s.length()); byte[] magnitude = digest.digest(); BigInteger bi = new BigInteger(1, magnitude); String hash = String.format("%0" + (magnitude.length << 1) + "x", bi); return hash; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } 

3 Comments

This one has a problem also. Try to encode q4m'x68n6_YDB4ty8VC4&}wqBtn^68W , it gives c70bb931f03b75af1591f261eb77d0b while the correct one should be 0c70bb931f03b75af1591f261eb77d0b First 0 disappers.
no dear it cause problem it will discard 0 i had tried in .net and java this fucntion discard 0
I have edited it to handle the leading zeros getting discarded ... now it works correctly :)
21

not working method:

public static String md5(String s) { try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest .getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); for (int i = 0; i < messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } 

result: 1865e62e7129927f6e4cd9bff104f0 (length 30)

working method:

public static final String md5(final String toEncrypt) { try { final MessageDigest digest = MessageDigest.getInstance("md5"); digest.update(toEncrypt.getBytes()); final byte[] bytes = digest.digest(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString().toLowerCase(); } catch (Exception exc) { return ""; // Impossibru! } } 

result: 1865e62e7129927f6e4c0d9bff1004f0 (length 32)

Comments

7
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String byteArrayToHex(byte[] array) { String s = ""; for (int i = 0; i < array.length; ++i) { int di = (array[i] + 256) & 0xFF; // Make it unsigned s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; } return s; } public static String digest(String s, String algorithm) { MessageDigest m = null; try { m = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return s; } m.update(s.getBytes(), 0, s.length()); return byteArrayToHex(m.digest()); } public static String md5(String s) { return digest(s, "MD5"); } 

2 Comments

yes 100%% work i had trie above fucntion all cause proble with 0 disacrding but this 3 function solution give me exact solution i had match this with .net md5 encription
Here is your solution with UTF-8 support : stackoverflow.com/a/19589939/537694
6

With @Donut solution, with UTF-8 encoded characters (eg: é) you have to use getBytes("UTF-8"). Here is my correction of the digest method:

private static char[] hextable = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; public static String byteArrayToHex(byte[] array) { String s = ""; for (int i = 0; i < array.length; ++i) { int di = (array[i] + 256) & 0xFF; // Make it unsigned s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; } return s; } public static String digest(String s, String algorithm) { MessageDigest m = null; try { m = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return s; } try { m.update(s.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); m.update(s.getBytes()); } return byteArrayToHex(m.digest()); } public static String md5(String s) { return digest(s, "MD5"); } 

Comments

5

The answer above is almost 100% correct. It will fail with unicode.

 MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); byte utf8_bytes[] = tag_xml.getBytes(); digest.update(utf8_bytes,0,utf8_bytes.length); hash = new BigInteger(1, digest.digest()).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } 

Need the length from the byte array not the string.

1 Comment

what is tag_xml here?? try q4m'x68n6_YDB4ty8VC4&}wqBtn^68W with the above code, the result is c70bb931f03b75af1591f261eb77d0b instead of 0c70bb931f03b75af1591f261eb77d0b as mentioned by @Sertap Bilal in the comment of the answer above this answer.
3

Donut's solution in a single function:

private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static String md5(String s) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); digest.update(s.getBytes(), 0, s.length()); byte[] bytes = digest.digest(); String hash = ""; for (int i = 0; i < bytes.length; ++i) { int di = (bytes[i] + 256) & 0xFF; hash = hash + hextable[(di >> 4) & 0xF] + hextable[di & 0xF]; } return hash; } catch (NoSuchAlgorithmException e) { } return ""; } 

Comments

3

If you didn't have security constraints and just wanted to convert String to a unique int. I'm writing it because that what I looked for and reached here.

String my_key int my_key.hashCode() 

if you have up to 10 chars it will even be unique See also https://stackoverflow.com/a/17583653/1984636

Comments

2

The following worked for me on Android without truncating any 0's infront:

MessageDigest md = null; String digest = null; try { md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(myStringToEncode.getBytes("UTF-8")); //converting byte array to Hexadecimal String StringBuilder sb = new StringBuilder(2*hash.length); for(byte b : hash){ sb.append(String.format("%02x", b&0xff)); } digest = sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return digest; 

Comments

2

This not missing '0'

 public static String md5(String string) { if (TextUtils.isEmpty(string)) { return ""; } MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); byte[] bytes = md5.digest(string.getBytes()); String result = ""; for (byte b : bytes) { String temp = Integer.toHexString(b & 0xff); if (temp.length() == 1) { temp = "0" + temp; } result += temp; } return result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } 

Comments

1
MessageDigest md = MessageDigest.getInstance("MD5"); md.update('yourstring'); byte[] digest = md.digest(); StringBuffer sb = new StringBuffer(); for (byte b : digest) { sb.append(String.format("%02x", (0xFF & b))); } 

It's late for the author, but before this, I get Integer.toHexString(0xff&b) , which strips leading 0s from the hex string. It makes me struggled for a long time. Hope useful for some guys.

Comments

1

if you are using guava:

public String generateMd5(String input) { HashFunction hf = Hashing.md5(); Hasher hasher = hf.newHasher(); HashCode hc = hasher.putString(input, StandardCharsets.UTF_8).hash(); return hc.toString(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.