/*
 * Copyright 2012 GitHub Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.mobile.util;

import static java.util.Locale.US;
import android.text.TextUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * Helper to get a gravatar hash for an email
 */
public class GravatarUtils {

    /**
     * Length of generated hash
     */
    public static final int HASH_LENGTH = 32;

    /**
     * Algorithm used for hashing
     */
    public static final String HASH_ALGORITHM = "MD5"; //$NON-NLS-1$

    /**
     * Charset used for hashing
     */
    public static final String CHARSET = "CP1252"; //$NON-NLS-1$

    private static String digest(final String value) {
        byte[] digested;
        try {
            digested = MessageDigest.getInstance(HASH_ALGORITHM).digest(
                    value.getBytes(CHARSET));
        } catch (NoSuchAlgorithmException e) {
            return null;
        } catch (UnsupportedEncodingException e) {
            return null;
        }

        String hashed = new BigInteger(1, digested).toString(16);
        int padding = HASH_LENGTH - hashed.length();
        if (padding == 0)
            return hashed;

        char[] zeros = new char[padding];
        Arrays.fill(zeros, '0');
        return new StringBuilder(HASH_LENGTH).append(zeros).append(hashed)
                .toString();
    }

    /**
     * Get avatar hash for specified e-mail address
     *
     * @param email
     * @return hash
     */
    public static String getHash(String email) {
        if (TextUtils.isEmpty(email))
            return null;
        email = email.trim().toLowerCase(US);
        return email.length() > 0 ? digest(email) : null;
    }
}
@@ -997,37 +997,38 @@
 sh%0A     */%0A    p
-ublic
+rivate
  static final in
@@ -1063,25 +1063,23 @@
 %0A     * 
-Algorithm
+Charset
  used fo
@@ -1093,37 +1093,38 @@
 ng%0A     */%0A    p
-ublic
+rivate
  static final St
@@ -1132,45 +1132,27 @@
 ing 
+C
 HA
-SH_ALGORITHM = %22MD5%22; //$NON-NLS-1$
+RSET = %22CP1252%22;
 %0A%0A  
@@ -1156,39 +1156,41 @@
 %0A    /**%0A     * 
-Charset
+Algorithm
  used for hashin
@@ -1196,37 +1196,38 @@
 ng%0A     */%0A    p
-ublic
+rivate
  static final St
@@ -1228,128 +1228,69 @@
 nal 
-String CHARSET = %22CP1252%22; //$NON-NLS-1$%0A%0A    private static String digest(final String value) %7B%0A        byte%5B%5D
+MessageDigest MD5;%0A%0A    static %7B%0A        MessageDigest
  digest
-ed
 ;%0A  
@@ -1319,18 +1319,16 @@
   digest
-ed
  = Messa
@@ -1352,42 +1352,98 @@
 nce(
-HASH_ALGORITHM).digest(%0A  
+%22MD5%22);%0A        %7D catch (NoSuchAlgorithmException e) %7B%0A            digest = null;%0A
         
     
@@ -1438,24 +1438,26 @@
         
+%7D%0A
         
   value.
@@ -1452,182 +1452,394 @@
     
-  value.getBytes(CHARSET))
+MD5 = digest
 ;%0A    
+%7D%0A%0A
     
-%7D catch (NoSuchAlgorithmException e) %7B%0A            return null;%0A        %7D catch (UnsupportedEncodingException e) %7B%0A            return null
+private static String digest(final String value) %7B%0A        if (MD5 == null)%0A            return null;%0A%0A        byte%5B%5D bytes;%0A        try %7B%0A            bytes = value.getBytes(CHARSET);%0A        %7D catch (UnsupportedEncodingException e) %7B%0A            return null;%0A        %7D%0A%0A        synchronized (MD5) %7B%0A            MD5.reset();%0A            bytes = MD5.digest(bytes)
 ;%0A  
@@ -1893,16 +1893,13 @@
 (1, 
-digested
+bytes
 ).to

Use single MessageDigest instance across all hash calls