Android Open Source - android-password-strength-indicator Password Strength View






From Project

Back to project page android-password-strength-indicator.

License

The source code is released under:

MIT License

If you think the Android project android-password-strength-indicator listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package uk.co.mattallensoftware.passwordstrengthindicator;
//from   w w w . jav a2  s  . c o m
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Matt Allen
 * 01/07/14
 * http://www.mattallensoftware.co.uk
 * mattallen092@gmail.com
 *
 * <p>
 * This View is designed to indicate how secure a user-entered password is in a visual way to
 * relay to the user if they need to make it stronger. The strength of the password can be set
 * at creation (or after) which will decide whether their password is strong enough.
 * </p>
 *
 * <p>
 * The password strength is decided by an index of 20. The minimum score needed to pass is 10
 * which means the String has met the conditions imposed by the strength test, but can be improved.
 * If the password scores 10-19 it is considered weak, and only if it scores 20 will it be
 * considered strong.
 * </p>
 */
public class PasswordStrengthView extends View {

    protected static final int      COLOR_FAIL = Color.parseColor("#e74c3c");
    protected static final int      COLOR_WEAK = Color.parseColor("#e67e22");
    protected static final int     COLOR_STRONG = Color.parseColor("#2ecc71");

    protected int                   mMinWidth, mMinHeight;
    protected Paint                 mIndicatorPaint, mGuidePaint;
    protected int           mIndicatorHeight, mIndicatorWidth, mCurrentScore;

    protected boolean                 mShowGuides = true;

    /**
     * Used to define that the indicator should only be looking
     * for a weak password. The bare minimum is used here to let
     * the user continue.
     */
    public static final int         STRENGTH_WEAK = 0;

    /**
     * A fairly strict rule for generating a password. It encourages a password that is
     * less easy to crack.
     */
    public static final int         STRENGTH_MEDIUM = 1;

    /**
     * A strong algorithm that encourages very strong passwords that should be fairly long, with
     * non-alphanumeric, numbers, and upper case.
     */
    public static final int         STRENGTH_STRONG = 2;

    private int                     mStrengthRequirement = -1;
    protected String                mPassword;

    public PasswordStrengthView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray style = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.PasswordStrengthView,
                0, 0);

        try {
            mStrengthRequirement = style.getInteger(R.styleable.PasswordStrengthView_strength, STRENGTH_MEDIUM);
            mShowGuides = style.getBoolean(R.styleable.PasswordStrengthView_showGuides, true);
        } catch (Exception e){
            e.printStackTrace();
        }
        // Create and style the paint used for drawing the guide on the indicator
        mGuidePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mGuidePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mGuidePaint.setColor(Color.BLACK);
        // Create and style paint for indicator
        mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mIndicatorPaint.setStyle(Paint.Style.FILL);
    }

    /**
     * This view can determine if the password entered by the user is acceptable for
     * use by your use case. This is based on the strength requirement you have set.
     * @return True if requirement has been met
     */
    public boolean isStrengthRequirementMet() {
        return (mCurrentScore >= 10);
    }

    /**
     * Change the strength requirement of the password entered by the user. This will also
     * re-check the password already entered against these new requirements.
     * @param requiredStrength Use the public constants of this class to set
     */
    public void setStrengthRequirement(int requiredStrength) {
        if(requiredStrength >= 0 && requiredStrength <= 2){
            mStrengthRequirement = requiredStrength;
            if (mPassword != null && mPassword.length() > 0) {
                generatePasswordScore();
                // Update view with new score
                invalidate();
                requestLayout();
            }
        } else {
            throw new IndexOutOfBoundsException("Input out of expected range");
        }
    }

    /**
     * Update the password string to check strength of
     * @param passwordString String representation of user-input
     */
    public void setPassword(String passwordString) {
        if(passwordString != null && passwordString.length() > 0) {
            mPassword = passwordString;
            generatePasswordScore();
            // Update view with new score
            invalidate();
            requestLayout();
        } else {
            mPassword = "";
            mCurrentScore = 0;
            invalidate();
            requestLayout();
        }
    }

    /**
     * Private convenience method for adding to the password score
     * @param score Amount to be added to current score
     */
    protected void addToPasswordScore(int score) {
        // Limit max score
        if ((mCurrentScore + score) > 20){
            mCurrentScore = 20;
        } else {
            mCurrentScore = mCurrentScore + score;
        }
    }

    /**
     * Call this to determine the current strength requirement set on the algorithm
     * @return Int representation of the current strength set for the indicator
     */
    public int getStrengthRequirement() {
        return mStrengthRequirement;
    }

    /**
     * Generate a score based on the password. The password will already need to be stored
     * as a class member before running this.
     */
    protected void generatePasswordScore() {
        mCurrentScore = 0;
        int upperCase = getUppercaseCount(mPassword);
        int nonAlpha = getNonAlphanumericCount(mPassword);
        int numbers = getNumberCount(mPassword);
        switch (mStrengthRequirement){
            case STRENGTH_WEAK:
                addToPasswordScore(mPassword.length()*2);
                addToPasswordScore(upperCase*2);
                addToPasswordScore(nonAlpha*2);
                addToPasswordScore(numbers*2);
                break;

            case STRENGTH_MEDIUM:
                addToPasswordScore(mPassword.length());
                addToPasswordScore(upperCase);
                addToPasswordScore(nonAlpha*2);
                addToPasswordScore(numbers);
                break;

            case STRENGTH_STRONG:
                addToPasswordScore(mPassword.length()/2);
                // Cut the score in half to make this a very high requirement
                addToPasswordScore(upperCase);
                addToPasswordScore(nonAlpha);
                addToPasswordScore(numbers);
                break;
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
        int paddingX = getPaddingLeft();
        int paddingY = getPaddingTop();
        mIndicatorHeight = h - paddingY;
        mIndicatorWidth = w - paddingX;
    }

    /**
     * The standard parts of the onMeasure needed to create the password strength
     * indicator. Subclasses should call super.onMeasure, but also need to set
     * the minimum height and width in the constructor.
     * @param widthMeasureSpec The measurement given by the system
     * @param heightMeasureSpec The measurement given by the system
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Set minimum space for the view to do it's thing
        int minW = getPaddingLeft() + getPaddingRight() + mMinWidth;
        int w = resolveSizeAndState(minW, widthMeasureSpec, 1);
        // And give it enough height so it's visible
        int minH = mMinHeight + getPaddingBottom() + getPaddingTop();
        int h = resolveSizeAndState(minH, heightMeasureSpec, 0);
        // Feed these back into UIKit
        setMeasuredDimension(w, h);
    }

    /**
     * Set the colour of the indicator {@code Paint} to one that is appropriate
     * for the strength of the password.
     */
    protected void generateIndicatorColor() {
        int color = COLOR_FAIL;
        if (mCurrentScore >= 18) {
            color = COLOR_STRONG;
        }
        else if (mCurrentScore >= 10) {
            color = COLOR_WEAK;
        }
        mIndicatorPaint.setColor(color);
    }

    /**
     * Quick method to determine how many of the characters in a given string are upper case
     * @param stringToCheck The string to examine
     * @return Number of upper case characters
     */
    protected int getUppercaseCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length()-1;
        for (int i=0;i<=loops;i++){
            if(Character.isUpperCase(stringToCheck.charAt(i))) {
                score++;
            }
        }
        return score;
    }

    /**
     * A convenience method to determine how many characters in the given String aren't
     * letters or numbers.
     * @param stringToCheck
     * @return Number of characters that aren't numbers or letters
     */
    protected int getNonAlphanumericCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length()-1;
        for (int i=0;i<=loops;i++) {
            if(!Character.isLetter(stringToCheck.charAt(i)) &&
                    !Character.isDigit(stringToCheck.charAt(i))){
                score++;
            }
        }
        return score;
    }

    /**
     * A convenience method for returning the count of numbers in a given String.
     * @param stringToCheck
     * @return The numbers of digits in the String
     */
    protected int getNumberCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length()-1;
        for (int i=0;i<=loops;i++) {
            if(Character.isDigit(stringToCheck.charAt(i))) {
                score++;
            }
        }
        return score;
    }

    /**
     * Set the guides to show on the view.<br />
     * On the line style, the guides will show underneath<br />
     * On the rounded style, the guides will be shown on the outer edges.<br />
     * The view will be redrawn after the method is called.
     * @param showGuides True if you want the guides to be shown
     */
    public void setShowGuides(boolean showGuides) {
        mShowGuides = showGuides;
        if (mPassword != null && mPassword.length() > 0) {
            generatePasswordScore();
            invalidate();
            requestLayout();
        } else {
            mCurrentScore = 0;
            invalidate();
            requestLayout();
        }
    }

    /**
     * Determine whether the view is showing the guides for the password score
     * @return True if the guides are being shown
     */
    public boolean isShowingGuides() {
        return mShowGuides;
    }
}




Java Source Code List

uk.co.mattallensoftware.passwordstrengthindicator.ApplicationTest.java
uk.co.mattallensoftware.passwordstrengthindicator.IndicatorDemoActivity.java
uk.co.mattallensoftware.passwordstrengthindicator.PasswordStrengthBarView.java
uk.co.mattallensoftware.passwordstrengthindicator.PasswordStrengthRoundedView.java
uk.co.mattallensoftware.passwordstrengthindicator.PasswordStrengthView.java