📄 randpass.java
字号:
} break; case 'R':{ String alph = opts.getOptarg(); if (alph.length() != 0){ reqs.add(alph); } } break; case 'v':{ ver.add(opts.getOptarg()); } break; case 'n':{ try { number = Integer.parseInt(opts.getOptarg()); if (number <= 0) throw new NumberFormatException(); } catch (NumberFormatException nfe){ System.err.println(labels.getString("number.bad_argument")); System.exit(0); } } break; case 'r':{ try { maxreps = Integer.parseInt(opts.getOptarg()); if (maxreps < 0) throw new NumberFormatException(); } catch (NumberFormatException nfe){ System.err.println(labels.getString("number.bad_argument")); System.exit(0); } } break; case 'l':{ try { length = Integer.parseInt(opts.getOptarg()); if (length < 0) throw new NumberFormatException(); } catch (NumberFormatException nfe){ System.err.println(labels.getString("number.bad_argument")); System.exit(0); } } break; default:{ System.exit(0); } } } RandPass randPass = new RandPass(); randPass.setAlphabet(alphabet); randPass.setFirstAlphabet(firstAlphabet); randPass.setLastAlphabet(lastAlphabet); randPass.setMaxRepetition(maxreps); for (int i=0; i<reqs.size(); i++){ randPass.addRequirement(((String)(reqs.elementAt(i))).toCharArray(), 1); } for (int i=0; i<ver.size(); i++){ randPass.addVerifier((PasswordVerifier)((Class.forName((String)(ver.elementAt(i)))).newInstance())); } for (int i=0; i<number; i++){ System.out.println(randPass.getPass(length)); } } private Vector requirements = null; /** * Require that a certain number of characters from an * alphabet be present in generated passwords. * * @param alphabet set of letters that must be present * @param num number of letters from the alphabet that must be present. * * @since ostermillerutils 1.00.00 */ public void addRequirement(char[] alphabet, int num){ if (requirements == null) requirements = new Vector(); requirements.add(new Requirement(alphabet, num)); } /** * Set the alphabet used by this random password generator. * * @param alphabet Characters allowed in generated passwords. * @throws NullPointerException if the alphabet is null. * @throws ArrayIndexOutOfBoundsException if the alphabet has no elements. * * @since ostermillerutils 1.00.00 */ public void setAlphabet(char[] alphabet){ if (alphabet == null) throw new NullPointerException("Null alphabet"); if (alphabet.length == 0) throw new ArrayIndexOutOfBoundsException("No characters in alphabet"); this.alphabet = alphabet; } /** * Set the random number generator used by this random password generator. * * @param rand Secure random number generator to use when generating passwords. * * @since ostermillerutils 1.00.00 */ public void setRandomGenerator(SecureRandom rand){ this.rand = rand; } /** * Set the alphabet used by this random password generator for the first character * of passwords. * <p> * If the alphabet for the first character is set to null or has no elements, the main alphabet will * be used for the first character. * * @param alphabet Characters allowed for the first character of the passwords. * * @since ostermillerutils 1.00.00 */ public void setFirstAlphabet(char[] alphabet){ if (alphabet == null || alphabet.length == 0){ this.firstAlphabet = null; } else { this.firstAlphabet = alphabet; } } /** * Set the alphabet used by this random password generator for the last character * of passwords. * <p> * If the alphabet for the last character is set to null or has no elements, the main alphabet will * be used for the last character. * * @param alphabet Characters allowed for the last character of the passwords. * * @since ostermillerutils 1.00.00 */ public void setLastAlphabet(char[] alphabet){ if (alphabet == null || alphabet.length == 0){ this.lastAlphabet = null; } else { this.lastAlphabet = alphabet; } } /** * Set the maximum number of characters that may appear in sequence more than * once in a password. Your alphabet must be large enough to handle this * option. If your alphabet is {'a', 'b'} and you want 8 character passwords * in which no character appears twice (repetition 1) you are out of luck. * In such instances your request for no repetition will be ignored. * <p> * For example setRepetition(3) will allow a password ababab but not allow * abcabc. * <p> * Using this method can greatly reduce the pool of passwords that are generated. * For example if only one repetition is allowed then the pool of passwords * is the permutation of the alphabet rather than the combination. * * @param rep Maximum character repetition. * * @since ostermillerutils 1.00.00 */ public void setMaxRepetition(int rep){ this.repetition = rep - 1; } /** * Fill the given buffer with random characters. * <p> * Using this method, the password character array can easily * be reused for efficiency, or overwritten with new random * characters for security. * <p> * NOTE: If it is possible for a hacker to examine memory to find passwords, * the password should be overwritten in memory as soon as possible after i * is no longer in use. * * @param pass buffer that will hold the password. * @return the buffer, filled with random characters. * * @since ostermillerutils 1.00.00 */ public char[] getPassChars(char[] pass){ boolean verified = false; while (!verified){ int length = pass.length; for (int i=0; i<length; i++){ char[] useAlph = alphabet; if (i == 0 && firstAlphabet != null){ useAlph = firstAlphabet; } else if (i == length - 1 && lastAlphabet != null){ useAlph = lastAlphabet; } int size = avoidRepetition(useAlph, pass, i, repetition, useAlph.length); pass[i] = useAlph[rand.nextInt(size)]; } if (requirements != null) applyRequirements(pass); verified = true; for (int i=0; verified && verifiers != null && i<verifiers.size(); i++){ verified = ((PasswordVerifier)verifiers.elementAt(i)).verify(pass); } } return(pass); } private Vector verifiers = null; /** * Add a class that will verify passwords. No password * will be returned unless all verifiers approve of it. * * @param verifier class that performs verification of password. * * @since ostermillerutils 1.00.00 */ public void addVerifier(PasswordVerifier verifier){ if (verifiers == null) verifiers = new Vector(); verifiers.add(verifier); } private boolean[] touched = null; private int[] available = null; private void applyRequirements(char[] pass){ int size = requirements.size(); if (size > 0){ int length = pass.length; if (touched == null || touched.length < length) touched = new boolean[length]; if (available == null || available.length < length) available = new int[length]; for (int i=0; i<length; i++){ touched[i] = false; } for (int reqNum=0; reqNum<size; reqNum++){ Requirement req = (Requirement)requirements.elementAt(reqNum); // set the portion of this alphabet available for use. int reqUsedInd = req.alphabet.length; // figure out how much of this requirement is already fulfilled // and what is available to fulfill the rest of it. int fufilledInd = 0; int availableInd = 0; for (int i=0; i<length; i++){ if (arrayContains(req.alphabet, pass[i]) && fufilledInd < req.num){ fufilledInd++; touched[i] = true; if (repetition >= 0){ // move already used characters so they can' // be used again. This prevents repetition. reqUsedInd -= moveto(req.alphabet, reqUsedInd, pass[i]); // allow repetition if we have no other choice if(reqUsedInd < 0) reqUsedInd = req.alphabet.length; } } else if (!touched[i]){ available[availableInd] = i; availableInd++; } } // fulfill the requirement int toDo = req.num - fufilledInd; for (int i=0; i<toDo && availableInd>0; i++){ // pick a random available slot // and a random member of the available alphabet int slot = rand.nextInt(availableInd); char passChar = req.alphabet[rand.nextInt(reqUsedInd)]; pass[available[slot]] = passChar; touched[available[slot]] = true; // make the slot no longer available availableInd--; available[slot] = available[availableInd]; if (repetition >= 0){ // move already used characters so they can' // be used again. This prevents repetition. reqUsedInd -= moveto(req.alphabet, reqUsedInd, passChar); // allow repetition if we have no other choice if(reqUsedInd < 0) reqUsedInd = req.alphabet.length; } } } } } private static boolean arrayContains(char[] alph, char c){ for (int i=0; i<alph.length; i++){ if (alph[i] == c) return true; } return false; } /** * Avoid repetition (if possible) by moving all characters that would cause repetition to * the end of the alphabet and returning the size of the alphabet that may be used. * * @since ostermillerutils 1.00.00 */ private static int avoidRepetition(char[] alph, char[] pass, int passSize, int repetition, int alphSize){ if (repetition > -1){ // limit the alphabet to those characters that // will not cause repeating sequences int repPos = 0; while ((repPos = findRep(pass, repPos, passSize, repetition)) != -1){ // shuffle characters that would cause repetition // to the end of the alphabet and adjust the size // so that they will not be used. alphSize -= moveto(alph, alphSize, pass[repPos+repetition]); repPos++; } if (alphSize == 0) alphSize = alph.length; } return alphSize; } /** * Find a repetition of the desired length. The characters to search * for are located at pass[end-length] to pass[end] * * @since ostermillerutils 1.00.00 */ private static int findRep(char[] pass, int start, int end, int length){ for (int i=start; i<end-length; i++){ boolean onTrack = true; for (int j=0; onTrack && j<length; j++){ if (pass[i+j] != pass[end-length+j]) onTrack = false; } if(onTrack) return i; } return -1; } /** * move all of the given character to the end of the array * and return the number of characters moved. * * @since ostermillerutils 1.00.00 */ private static int moveto(char[] alph, int numGood, char c){ int count = 0; for (int i=0; i<numGood; i++){ if (alph[i] == c){ numGood--; char temp = alph[numGood]; alph[numGood] = alph[i]; alph[i] = temp; count++; } } return count; } /** * Generate a random password of the given length. * <p> * NOTE: If it is possible for a hacker to examine memory to find passwords, * the password should be overwritten in memory as soon as possible after i * is no longer in use. * * @param length The desired length of the generated password. * @return a random password * * @since ostermillerutils 1.00.00 */ public char[] getPassChars(int length){ return(getPassChars(new char[length])); } /** * Generate a random password of the default length (8). * <p> * NOTE: If it is possible for a hacker to examine memory to find passwords, * the password should be overwritten in memory as soon as possible after i * is no longer in use. * * @return a random password * * @since ostermillerutils 1.00.00 */ public char[] getPassChars(){ return(getPassChars(DEFAULT_PASSWORD_LENGTH)); } /** * Generate a random password of the given length. * <p> * NOTE: Strings can not be modified. If it is possible * for a hacker to examine memory to find passwords, getPassChars() * should be used so that the password can be zeroed out of memory * when no longer in use. * * @param length The desired length of the generated password. * @return a random password * * @see #getPassChars(int) * @since ostermillerutils 1.00.00 */ public String getPass(int length){ return(new String(getPassChars(new char[length]))); } /** * Generate a random password of the default length (8). * <p> * NOTE: Strings can not be modified. If it is possible * for a hacker to examine memory to find passwords, getPassChars() * should be used so that the password can be zeroed out of memory * when no longer in use. * * @return a random password * * @see #getPassChars() * @since ostermillerutils 1.00.00 */ public String getPass(){ return(getPass(DEFAULT_PASSWORD_LENGTH)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -