001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.SecureRandomUtil;
020    
021    /**
022     * @author Brian Wing Shun Chan
023     * @author Amos Fong
024     * @author Shuyang Zhou
025     */
026    public class PwdGenerator {
027    
028            public static final String KEY1 = "0123456789";
029    
030            public static final String KEY2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
031    
032            public static final String KEY3 = "abcdefghijklmnopqrstuvwxyz";
033    
034            public static String getPassword() {
035                    return getPassword(8, _KEYS);
036            }
037    
038            public static String getPassword(int length) {
039                    return getPassword(length, _KEYS);
040            }
041    
042            public static String getPassword(int length, String... keys) {
043                    if (keys == null) {
044                            throw new IllegalArgumentException("Keys are null");
045                    }
046    
047                    StringBundler fullKeySB = new StringBundler(keys);
048    
049                    String fullKey = fullKeySB.toString();
050    
051                    int fullKeyLength = fullKey.length();
052    
053                    int refreshPeriod = (int) (_MULTIPLIER / Math.log(fullKeyLength));
054    
055                    long secureLong = 0;
056    
057                    StringBuilder sb = new StringBuilder(length);
058    
059                    for (int i = 0; i < length; i++) {
060                            if ((i % refreshPeriod) == 0) {
061                                    secureLong = SecureRandomUtil.nextLong();
062                            }
063    
064                            int pos = Math.abs((int)(secureLong % fullKeyLength));
065    
066                            secureLong = secureLong / fullKeyLength;
067    
068                            sb.append(fullKey.charAt(pos));
069                    }
070    
071                    return sb.toString();
072            }
073    
074            public static String getPassword(String key, int length) {
075                    int keysCount = 0;
076    
077                    if (key.contains(KEY1)) {
078                            keysCount++;
079                    }
080    
081                    if (key.contains(KEY2)) {
082                            keysCount++;
083                    }
084    
085                    if (key.contains(KEY3)) {
086                            keysCount++;
087                    }
088    
089                    if (keysCount > length) {
090                            if (_log.isWarnEnabled()) {
091                                    _log.warn("Length is too short");
092                            }
093    
094                            length = keysCount;
095                    }
096    
097                    while (true) {
098                            String password = getPassword(length, key);
099    
100                            if (key.contains(KEY1)) {
101                                    if (Validator.isNull(StringUtil.extractDigits(password))) {
102                                            continue;
103                                    }
104                            }
105    
106                            if (key.contains(KEY2)) {
107                                    if (password.equals(StringUtil.toLowerCase(password))) {
108                                            continue;
109                                    }
110                            }
111    
112                            if (key.contains(KEY3)) {
113                                    if (password.equals(StringUtil.toUpperCase(password))) {
114                                            continue;
115                                    }
116                            }
117    
118                            return password;
119                    }
120            }
121    
122            public static String getPassword(
123                    String key, int length, boolean useAllKeys) {
124    
125                    if (useAllKeys) {
126                            return getPassword(key, length);
127                    }
128    
129                    return getPassword(length, key);
130            }
131    
132            public static String getPinNumber() {
133                    return getPassword(4, KEY1);
134            }
135    
136            private static final String[] _KEYS = {KEY1, KEY2, KEY3};
137    
138            private static final double _MULTIPLIER = Long.SIZE * Math.log(2);
139    
140            private static final Log _log = LogFactoryUtil.getLog(PwdGenerator.class);
141    
142    }