// Path: app/src/main/java/com/reddyetwo/hashmypass/app/TwikApplication.java
// public class TwikApplication extends Application {
// 
//     public static final String LOG_TAG = "TWIK";
//     private char[] mCachedMasterKey;
//     private boolean mTutorialDismissed = false;
//     private static TwikApplication mInstance;
// 
//     @Override
//     public void onCreate() {
//         super.onCreate();
//         mInstance = this;
//         LeakCanary.install(this);
//     }
// 
//     /**
//      * Return the Singleton instance of the {@link android.app.Application}
//      * @return the Singleton instance of the {@link android.app.Application}
//      */
//     public static TwikApplication getInstance() {
//         return mInstance;
//     }
// 
//     /**
//      * Get the tutorial dismissed flag.
//      *
//      * @return true if the tutorial has been dismissed, false otherwise.
//      */
//     public boolean getTutorialDismissed() {
//         return mTutorialDismissed;
//     }
// 
//     /**
//      * Set the tutorial dismissed flag. Once the tutorial has been dismissed, it is never shown again.
//      *
//      * @param tutorialDismissed the flag value
//      */
//     public void setTutorialDismissed(boolean tutorialDismissed) {
//         mTutorialDismissed = tutorialDismissed;
//     }
// 
//     /**
//      * Get the cached master key
//      *
//      * @return the cached master key
//      */
//     public char[] getCachedMasterKey() {
//         if (mCachedMasterKey == null || Preferences.getRememberMasterKeyMins(this) == 0) {
//             mCachedMasterKey = new char[]{};
//         }
//         return mCachedMasterKey;
//     }
// 
//     /**
//      * Wipe the cached master key
//      */
//     public void wipeCachedMasterKey() {
//         if (mCachedMasterKey != null) {
//             Arrays.fill(mCachedMasterKey, ' ');
//             mCachedMasterKey = null;
//         }
//     }
// 
//     /**
//      * Save master key to cache if enabled by user
//      *
//      * @param masterKey the master key
//      */
//     public void cacheMasterKey(char[] masterKey) {
//         if (Preferences.getRememberMasterKeyMins(this) > 0) {
//             mCachedMasterKey = Arrays.copyOf(masterKey, masterKey.length);
//         }
//     }
// }
// 
// Path: app/src/main/java/com/reddyetwo/hashmypass/app/data/PasswordType.java
// public enum PasswordType {
//     ALPHANUMERIC_AND_SPECIAL_CHARS,
//     ALPHANUMERIC,
//     NUMERIC
// }
// 
// Path: app/src/main/java/com/reddyetwo/hashmypass/app/util/SecurePassword.java
// public class SecurePassword {
// 
//     private SecurePassword() {
// 
//     }
// 
//     /**
//      * Get the password stored in an {@link android.text.Editable} object
//      *
//      * @param s the {@link android.text.Editable} instance
//      * @return the password
//      */
//     public static char[] getPassword(Editable s) {
//         int length = s.length();
//         char[] password = new char[length];
//         for (int i = 0; i < length; i++) {
//             password[i] = s.charAt(i);
//         }
//         return password;
//     }
// 
//     /**
//      * Convert a password stored as a char array to a byte array
//      *
//      * @param chars the password as a char array
//      * @return the password as a byte array
//      */
//     public static byte[] toBytes(char[] chars) {
//         CharBuffer charBuffer = CharBuffer.wrap(chars);
//         ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
//         byte[] bytes =
//                 Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
// 
//         // Clear sensitive data
//         Arrays.fill(charBuffer.array(), '\u0000');
//         Arrays.fill(byteBuffer.array(), (byte) 0);
//         return bytes;
//     }
// }


import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
import android.util.Log;
import com.reddyetwo.hashmypass.app.TwikApplication;
import com.reddyetwo.hashmypass.app.data.PasswordType;
import com.reddyetwo.hashmypass.app.util.SecurePassword;
     * @param tag          the tag name
     * @param masterKey    the master key
     * @param privateKey   the private key
     * @param length       the password length
     * @param passwordType the password type
     * @return the hashed password
     */
    public static String hashTagWithKeys(String tag, char[] masterKey, String privateKey,
                                         int length, PasswordType passwordType) {
        // First, hash the tag with the private key (in the case that it is used)
        String tagToHash = privateKey == null ? tag :
                hashKey(privateKey, tag.toCharArray(), INTERMEDIATE_HASH_SIZE,
                        PasswordType.ALPHANUMERIC_AND_SPECIAL_CHARS);

        // Then, hash the result with the master key
        return hashKey(tagToHash, masterKey, length, passwordType);
    }

    /**
     * Calculate the digest of an input string
     *
     * @param input the input string
     * @return the digest of the input string
     */
    public static byte[] calculateDigest(char[] input) {
        MessageDigest messageDigest;
        byte[] result;

        try {
            messageDigest = MessageDigest.getInstance(DIGEST_MD5);
// Path: app/src/main/java/com/reddyetwo/hashmypass/app/TwikApplication.java
// public class TwikApplication extends Application {
// 
//     public static final String LOG_TAG = "TWIK";
//     private char[] mCachedMasterKey;
//     private boolean mTutorialDismissed = false;
//     private static TwikApplication mInstance;
// 
//     @Override
//     public void onCreate() {
//         super.onCreate();
//         mInstance = this;
//         LeakCanary.install(this);
//     }
// 
//     /**
//      * Return the Singleton instance of the {@link android.app.Application}
//      * @return the Singleton instance of the {@link android.app.Application}
//      */
//     public static TwikApplication getInstance() {
//         return mInstance;
//     }
// 
//     /**
//      * Get the tutorial dismissed flag.
//      *
//      * @return true if the tutorial has been dismissed, false otherwise.
//      */
//     public boolean getTutorialDismissed() {
//         return mTutorialDismissed;
//     }
// 
//     /**
//      * Set the tutorial dismissed flag. Once the tutorial has been dismissed, it is never shown again.
//      *
//      * @param tutorialDismissed the flag value
//      */
//     public void setTutorialDismissed(boolean tutorialDismissed) {
//         mTutorialDismissed = tutorialDismissed;
//     }
// 
//     /**
//      * Get the cached master key
//      *
//      * @return the cached master key
//      */
//     public char[] getCachedMasterKey() {
//         if (mCachedMasterKey == null || Preferences.getRememberMasterKeyMins(this) == 0) {
//             mCachedMasterKey = new char[]{};
//         }
//         return mCachedMasterKey;
//     }
// 
//     /**
//      * Wipe the cached master key
//      */
//     public void wipeCachedMasterKey() {
//         if (mCachedMasterKey != null) {
//             Arrays.fill(mCachedMasterKey, ' ');
//             mCachedMasterKey = null;
//         }
//     }
// 
//     /**
//      * Save master key to cache if enabled by user
//      *
//      * @param masterKey the master key
//      */
//     public void cacheMasterKey(char[] masterKey) {
//         if (Preferences.getRememberMasterKeyMins(this) > 0) {
//             mCachedMasterKey = Arrays.copyOf(masterKey, masterKey.length);
//         }
//     }
// }
// 
// Path: app/src/main/java/com/reddyetwo/hashmypass/app/data/PasswordType.java
// public enum PasswordType {
//     ALPHANUMERIC_AND_SPECIAL_CHARS,
//     ALPHANUMERIC,
//     NUMERIC
// }
// 
// Path: app/src/main/java/com/reddyetwo/hashmypass/app/util/SecurePassword.java
// public class SecurePassword {
// 
//     private SecurePassword() {
// 
//     }
// 
//     /**
//      * Get the password stored in an {@link android.text.Editable} object
//      *
//      * @param s the {@link android.text.Editable} instance
//      * @return the password
//      */
//     public static char[] getPassword(Editable s) {
//         int length = s.length();
//         char[] password = new char[length];
//         for (int i = 0; i < length; i++) {
//             password[i] = s.charAt(i);
//         }
//         return password;
//     }
// 
//     /**
//      * Convert a password stored as a char array to a byte array
//      *
//      * @param chars the password as a char array
//      * @return the password as a byte array
//      */
//     public static byte[] toBytes(char[] chars) {
//         CharBuffer charBuffer = CharBuffer.wrap(chars);
//         ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
//         byte[] bytes =
//                 Arrays.copyOfRange(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit());
// 
//         // Clear sensitive data
//         Arrays.fill(charBuffer.array(), '\u0000');
//         Arrays.fill(byteBuffer.array(), (byte) 0);
//         return bytes;
//     }
// }


// Path: app/src/main/java/com/reddyetwo/hashmypass/app/hash/PasswordHasher.java
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
import android.util.Log;
import com.reddyetwo.hashmypass.app.TwikApplication;
import com.reddyetwo.hashmypass.app.data.PasswordType;
import com.reddyetwo.hashmypass.app.util.SecurePassword;

     * @param tag          the tag name
     * @param masterKey    the master key
     * @param privateKey   the private key
     * @param length       the password length
     * @param passwordType the password type
     * @return the hashed password
     */
    public static String hashTagWithKeys(String tag, char[] masterKey, String privateKey,
                                         int length, PasswordType passwordType) {
        // First, hash the tag with the private key (in the case that it is used)
        String tagToHash = privateKey == null ? tag :
                hashKey(privateKey, tag.toCharArray(), INTERMEDIATE_HASH_SIZE,
                        PasswordType.ALPHANUMERIC_AND_SPECIAL_CHARS);

        // Then, hash the result with the master key
        return hashKey(tagToHash, masterKey, length, passwordType);
    }

    /**
     * Calculate the digest of an input string
     *
     * @param input the input string
     * @return the digest of the input string
     */
    public static byte[] calculateDigest(char[] input) {
        MessageDigest messageDigest;
        byte[] result;

        try {
            messageDigest = MessageDigest.getInstance(DIGEST_MD5);
            result = messageDigest.digest(SecurePassword.toBytes(input));