/*
* Password Management Servlets (PWM)
* http://www.pwm-project.org
*
* Copyright (c) 2006-2009 Novell, Inc.
* Copyright (c) 2009-2017 The PWM Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package password.pwm.util;
public class PasswordCharCounter {
private final String password;
private final int passwordLength;
public PasswordCharCounter(final String password) {
this.password = password;
this.passwordLength = password.length();
}
public int getNumericCharCount() {
return getNumericChars().length();
}
public String getNumericChars() {
return returnCharsOfType(password, CharType.NUMBER);
}
public int getUpperCharCount() {
return getUpperChars().length();
}
public String getUpperChars() {
return returnCharsOfType(password, CharType.UPPERCASE);
}
public int getAlphaCharCount() {
return getAlphaChars().length();
}
public String getAlphaChars() {
return returnCharsOfType(password, CharType.LETTER);
}
public int getNonAlphaCharCount() {
return getNonAlphaChars().length();
}
public String getNonAlphaChars() {
return returnCharsOfType(password, CharType.NON_LETTER);
}
public int getLowerCharCount() {
return getLowerChars().length();
}
public String getLowerChars() {
return returnCharsOfType(password, CharType.LOWERCASE);
}
public int getSpecialCharsCount() {
return getSpecialChars().length();
}
public String getSpecialChars() {
return returnCharsOfType(password, CharType.SPECIAL);
}
public int getRepeatedChars() {
int numberOfRepeats = 0;
final CharSequence passwordL = password.toString().toLowerCase();
for (int i = 0; i < passwordLength - 1; i++) {
int loopRepeats = 0;
final char loopChar = passwordL.charAt(i);
for (int j = i; j < passwordLength; j++) {
if (loopChar == passwordL.charAt(j)) {
loopRepeats++;
}
}
if (loopRepeats > numberOfRepeats) {
numberOfRepeats = loopRepeats;
}
}
return numberOfRepeats;
}
public int getSequentialRepeatedChars() {
int numberOfRepeats = 0;
final CharSequence passwordL = password.toString().toLowerCase();
for (int i = 0; i < passwordLength - 1; i++) {
int loopRepeats = 0;
final char loopChar = passwordL.charAt(i);
for (int j = i; j < passwordLength; j++) {
if (loopChar == passwordL.charAt(j)) {
loopRepeats++;
} else {
break;
}
}
if (loopRepeats > numberOfRepeats) {
numberOfRepeats = loopRepeats;
}
}
return numberOfRepeats;
}
public int getSequentialNumericChars() {
int numberOfRepeats = 0;
for (int i = 0; i < passwordLength - 1; i++) {
int loopRepeats = 0;
for (int j = i; j < passwordLength; j++) {
if (Character.isDigit(password.charAt(j))) {
loopRepeats++;
} else {
break;
}
}
if (loopRepeats > numberOfRepeats) {
numberOfRepeats = loopRepeats;
}
}
return numberOfRepeats;
}
public int getSequentialAlphaChars() {
int numberOfRepeats = 0;
for (int i = 0; i < passwordLength - 1; i++) {
int loopRepeats = 0;
for (int j = i; j < passwordLength; j++) {
if (Character.isLetter(password.charAt(j))) {
loopRepeats++;
} else {
break;
}
}
if (loopRepeats > numberOfRepeats) {
numberOfRepeats = loopRepeats;
}
}
return numberOfRepeats;
}
public int getUniqueChars() {
final StringBuilder sb = new StringBuilder();
final String passwordL = password.toString().toLowerCase();
for (int i = 0; i < passwordLength; i++) {
final char loopChar = passwordL.charAt(i);
if (sb.indexOf(String.valueOf(loopChar)) == -1) {
sb.append(loopChar);
}
}
return sb.length();
}
public int getOtherLetterCharCount() {
return getOtherLetterChars().length();
}
public String getOtherLetterChars() {
return returnCharsOfType(password, CharType.OTHER_LETTER);
}
public boolean isFirstNumeric() {
return password.length() > 0 && Character.isDigit(password.charAt(0));
}
public boolean isLastNumeric() {
return password.length() > 0 && Character.isDigit(password.charAt(password.length() - 1));
}
public boolean isFirstSpecial() {
return password.length() > 0 && !Character.isLetterOrDigit(password.charAt(0));
}
public boolean isLastSpecial() {
return password.length() > 0 && !Character.isLetterOrDigit(password.charAt(password.length() - 1));
}
private static String returnCharsOfType(final String input, final CharType charType) {
final int passwordLength = input.length();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < passwordLength; i++) {
final char nextChar = input.charAt(i);
if (charType.getCharTester().isType(nextChar)) {
sb.append(nextChar);
}
}
return sb.toString();
}
private enum CharType {
UPPERCASE(new CharTester() {
public boolean isType(final char character)
{
return Character.isUpperCase(character);
}
}),
LOWERCASE(new CharTester() {
public boolean isType(final char character)
{
return Character.isLowerCase(character);
}
}),
SPECIAL(new CharTester() {
public boolean isType(final char character)
{
return !Character.isLetterOrDigit(character);
}
}),
NUMBER(new CharTester() {
public boolean isType(final char character)
{
return Character.isDigit(character);
}
}),
LETTER(new CharTester() {
public boolean isType(final char character)
{
return Character.isLetter(character);
}
}),
NON_LETTER(new CharTester() {
public boolean isType(final char character)
{
return !Character.isLetter(character);
}
}),
OTHER_LETTER(new CharTester() {
public boolean isType(final char character)
{
return Character.getType(character) == Character.OTHER_LETTER;
}
}),
;
private final CharTester charTester;
CharType(final CharTester charClassType)
{
this.charTester = charClassType;
}
public CharTester getCharTester()
{
return charTester;
}
}
private interface CharTester {
boolean isType(char character);
}
}