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.
- 
                    1A hash is unidirectional, if you want to be able to decrypt data you can't store with a constant length IMHO – Alois Cochard Oct 14 '10 at 14:41
- 
                    2I 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. – Jorsher Oct 14 '10 at 14:48
- 
                    1No offense but the title of your question is misleading – Ton Snoei Sep 23 '15 at 08:12
12 Answers
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
- 
                    2MD5, 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. – Jorsher Nov 09 '10 at 14:24
- 
                    31This code does not work properly. Some "0" characters becomes missing in the generated string. I don't know why, but that's the case. – Sertalp B. Cay Dec 28 '11 at 00:23
- 
                    8There's a special condition when this code fails. When the first of two digit Hex number is zero. This code is better: http://stackoverflow.com/a/6565597/221135 – Jaec Feb 16 '13 at 09:46
- 
                    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 – CoronaPintu Jun 14 '13 at 10:58
- 
                    The padding problem is very easy to fix. Before appending the hex `String` of each `byte` (in the for loop), prepend "0" until the length is 2, and then append it to `hexString`. Works perfectly for me now. – Steven Byle Aug 19 '13 at 21:27
- 
                    MD5 is indeed breakable, albeit rather difficult to the inexperienced. See http://ehash.iaik.tugraz.at/wiki/MD and http://www.mscs.dal.ca/~selinger/md5collision/ – Chris Mar 09 '14 at 16:56
- 
                    2Agree with @SertalpBilal, correct answer is here http://stackoverflow.com/a/4846511/1092591 – Alexandr Mar 26 '16 at 15:53
- 
                    
- 
                    
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 "";
}
 
    
    - 30,051
- 12
- 94
- 120
 
    
    - 4,763
- 1
- 25
- 19
- 
                    6This 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. – Sertalp B. Cay Dec 28 '11 at 00:25
- 
                    2no dear it cause problem it will discard 0 i had tried in .net and java this fucntion discard 0 – CoronaPintu Jun 14 '13 at 11:03
- 
                    7I have edited it to handle the leading zeros getting discarded ... now it works correctly :) – Yash Sampat Sep 10 '15 at 13:23
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)
 
    
    - 402
- 7
- 16
 
    
    - 336
- 2
- 6
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");
}
 
    
    - 157
- 2
- 6
- 
                    2yes 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 – CoronaPintu Jun 14 '13 at 11:08
- 
                    Here is your solution with UTF-8 support : http://stackoverflow.com/a/19589939/537694 – Climbatize Oct 25 '13 at 12:31
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");
}
 
    
    - 1,103
- 19
- 34
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.
 
    
    - 148
- 2
- 8
- 
                    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. – Gautam Mandsorwale Jan 03 '13 at 14:23
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 "";
}
 
    
    - 551
- 1
- 6
- 15
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
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;
 
    
    - 4,593
- 1
- 33
- 37
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 "";
    }
 
    
    - 19
- 8
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.
 
    
    - 73
- 9
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();
}
 
    
    - 3,198
- 2
- 35
- 51
 
     
     
     
    