001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1
003: * The contents of this file are subject to the Mozilla Public License Version
004: * 1.1 (the "License"); you may not use this file except in compliance with
005: * the License. You may obtain a copy of the License at
006: * http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the
011: * License.
012: *
013: * The Original Code is Riot.
014: *
015: * The Initial Developer of the Original Code is
016: * Neteye GmbH.
017: * Portions created by the Initial Developer are Copyright (C) 2006
018: * the Initial Developer. All Rights Reserved.
019: *
020: * Contributor(s):
021: * Felix Gnass [fgnass at neteye dot de]
022: *
023: * ***** END LICENSE BLOCK ***** */
024: package org.riotfamily.common.util;
025:
026: import java.util.Random;
027:
028: /**
029: * Class that generates random strings suitable for use as passwords.
030: *
031: * @author Felix Gnass [fgnass at neteye dot de]
032: */
033: public class PasswordGenerator {
034:
035: private static final String UPPER_CHARS = "ABCDEFGHJKLKMNPQRSTWXYZ";
036: private static final String AMBIGUOUS_UPPER_CHARS = "IOUV";
037:
038: private static final String LOWER_CHARS = "abcdefghijkmnpqrstwxyz";
039: private static final String AMBIGUOUS_LOWER_CHARS = "louv";
040:
041: private static final String DIGITS = "23456789";
042: private static final String AMBIGUOUS_DIGITS = "01";
043:
044: private static PasswordGenerator defaultInstance = new PasswordGenerator();
045:
046: private Random random = new Random();
047:
048: private boolean useUpperChars;
049: private boolean useLowerChars;
050: private boolean useDigits;
051:
052: private boolean includeAmbiguous;
053:
054: private int passwordLength;
055:
056: private StringBuffer chars;
057:
058: public PasswordGenerator() {
059: this (8, true, true, true);
060: }
061:
062: public PasswordGenerator(int passwordLength, boolean useUpperChars,
063: boolean useLowerChars, boolean useDigits) {
064:
065: this .passwordLength = passwordLength;
066: this .useUpperChars = useUpperChars;
067: this .useLowerChars = useLowerChars;
068: this .useDigits = useDigits;
069: }
070:
071: public static PasswordGenerator getDefaultInstance() {
072: return defaultInstance;
073: }
074:
075: public boolean getUseUpperChars() {
076: return useUpperChars;
077: }
078:
079: public boolean getUseLowerChars() {
080: return useLowerChars;
081: }
082:
083: public boolean getUseDigits() {
084: return useDigits;
085: }
086:
087: public boolean isIncludeAmbiguous() {
088: return includeAmbiguous;
089: }
090:
091: public void setUseUpperChars(boolean v) {
092: check();
093: useUpperChars = v;
094: }
095:
096: public void setUseLowerChars(boolean v) {
097: check();
098: useLowerChars = v;
099: }
100:
101: public void setUseDigits(boolean v) {
102: check();
103: useDigits = v;
104: }
105:
106: public void setIncludeAmbiguous(boolean includeAmbiguous) {
107: check();
108: this .includeAmbiguous = includeAmbiguous;
109: }
110:
111: public void setPasswordLength(int i) {
112: passwordLength = i;
113: }
114:
115: public int getPasswordLength() {
116: return passwordLength;
117: }
118:
119: protected void check() {
120: if (chars != null) {
121: throw new IllegalStateException(
122: "PasswordGenerator is already configured");
123: }
124: }
125:
126: protected void prepare() {
127: if (chars == null) {
128: chars = new StringBuffer();
129: if (getUseLowerChars()) {
130: chars.append(LOWER_CHARS);
131: if (includeAmbiguous) {
132: chars.append(AMBIGUOUS_LOWER_CHARS);
133: }
134: }
135: if (getUseUpperChars()) {
136: chars.append(UPPER_CHARS);
137: if (includeAmbiguous) {
138: chars.append(AMBIGUOUS_UPPER_CHARS);
139: }
140: }
141: if (getUseDigits()) {
142: chars.append(DIGITS);
143: if (includeAmbiguous) {
144: chars.append(AMBIGUOUS_DIGITS);
145: }
146: }
147: if (chars.length() == 0) {
148: throw new IllegalStateException(
149: "At least one type of characters must be specified");
150: }
151: }
152: }
153:
154: public long getPossibleCombinations() {
155: return (long) Math.pow(chars.length(), passwordLength);
156: }
157:
158: public int getChanceToGuess(long validPasswords) {
159: //return (int) (100 / (validPasswords / getPossibleCombinations()));
160: return (int) (getPossibleCombinations() / validPasswords);
161: }
162:
163: public String generate() {
164: prepare();
165: StringBuffer buffer = new StringBuffer(passwordLength);
166:
167: // Loop through the password characters and assign each
168: // a random character from the set of allowed characters
169:
170: for (int i = 0; i < passwordLength; i++) {
171: int index = random.nextInt() % chars.length();
172: index = Math.abs(index);
173: char c = chars.charAt(index);
174: buffer.append(c);
175: }
176: return buffer.toString();
177: }
178:
179: }
|