我该如何创建密码?

我想给一些用户提供一百万个密码:

  1. 它必须至少有6个字符
  2. 它必须有数字和字母

我应该在这里使用Random吗? 怎么样?

来自Apache Commons Lang的RandomStringUtils提供了一些生成随机String的方法,可以用作密码。


以下是一些8字符密码创建示例:

 // Passwords with only alphabetic characters. for (int i = 0; i < 8; i++) { System.out.println(RandomStringUtils.randomAlphabetic(8)); } System.out.println("--------"); // Passwords with alphabetic and numeric characters. for (int i = 0; i < 8; i++) { System.out.println(RandomStringUtils.randomAlphanumeric(8)); } 

这会产生以下结果:

 zXHzaLdG oDtlFDdf bqPbXVfq tzQUWuxU qBHBRKQP uBLwSvnt gzBcTnIm yTUgXlCc -------- khDzEFD2 cHz1p6yJ 3loXcBau F6NJAQr7 PyfN079I 8tJye7bu phfwpY6y 62q27YRt 

当然,您还有一些方法可能会限制密码生成所允许的字符集:

 for (int i = 0; i < 8; i++) { System.out.println(RandomStringUtils.random(8, "abcDEF123")); } 

将仅创建包含字符a,b,c,D,E,F,1,2或3的密码:

 D13DD1Eb cac1Dac2 FE1bD2DE 2ab3Fb3D 213cFEFD 3c2FEDDF FDbFcc1E b2cD1c11 

出于安全原因(即密码 )使用Apache的RandomStringUtils ,结合使用SecureRandom源非常重要:

 RandomStringUtils.random(6, 0, 0, true, true, null, new SecureRandom()); 

使用SecureRandom ,它提供更随机的密码。

您可以使用以下内容创建单个密码(注意:未经测试的代码)。

 // put here all characters that are allowed in password char[] allowedCharacters = {'a','b','c','1','2','3','4'}; SecureRandom random = new SecureRandom(); StringBuffer password = new StringBuffer(); for(int i = 0; i < PASSWORD_LENGTH; i++) { password.append(allowedCharacters[ random.nextInt(allowedCharacters.length) ]); } 

请注意,这并不能保证每个密码都包含数字和字符。

这是我写的一段时间:

 package com.stackoverflow.does.my.code.for.me; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; public class PasswordUtil { /** Minimum password length = 6 */ public static final int MIN_PASSWORD_LENGTH = 6; /** Maximum password length = 8 */ public static final int MAX_PASSWORD_LENGTH = 8; /** Uppercase characters AZ */ public static final char[] UPPERS = new char[26]; /** Lowercase characters az */ public static final char[] LOWERS = new char[26]; /** * Printable non-alphanumeric characters, excluding space. */ public static final char[] SPECIALS = new char[32]; public static final char[] DIGITS = new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; static { // Static initializer block for populating arrays int U = 'A'; int l = 'a'; int d = '0'; for (int i = 0; i < 26; i++) { UPPERS[i] = (char) (U + i); LOWERS[i] = (char) (l + i); if (i < 10) { DIGITS[i] = (char) (d + i); } } int p = 0; for (int s = 33; s < 127; s++) { char specialChar = (char) 32; if (s >= 'a' && s <= 'z') s = 'z' + 1; // jump over 'a' to 'z' else if (s >= 'A' && s <= 'Z') s = 'Z' + 1; // jump over 'A' to 'Z' else if (s >= '0' && s <= '9') s = '9' + 1; // jump over '0' to '9' specialChar = (char) s; SPECIALS[p] = specialChar; p++; } } public String generatePassword() { List activeSets = new ArrayList(4); List inactiveSets = new ArrayList(4); activeSets.add(UPPERS); activeSets.add(LOWERS); activeSets.add(SPECIALS); activeSets.add(DIGITS); SecureRandom random = new SecureRandom(); int passwordLength = 5 + random.nextInt(3); StringBuffer password = new StringBuffer(passwordLength + 1); for (int p = 0; p <= passwordLength; p++) { char[] randomSet = null; if (activeSets.size() > 1) { int rSet = random.nextInt(activeSets.size()); randomSet = activeSets.get(rSet); inactiveSets.add(randomSet); activeSets.remove(rSet); } else { randomSet = activeSets.get(0); inactiveSets.add(randomSet); activeSets.clear(); activeSets.addAll(inactiveSets); inactiveSets.clear(); } int rChar = random.nextInt(randomSet.length); char randomChar = randomSet[rChar]; password.append(randomChar); } return password.toString(); } } 

这也很好:

 String password = Integer.toString((int) (Math.random() * Integer.MAX_VALUE), 36); 

但是,它并不保证密码始终包含数字和字母,但大多数上述建议也不会这样做。

我会做的是这样的事情:

  1. 创建两个数组,一个包含允许的字母,另一个包含允许的数字。
  2. 使用Random来确定密码的长度。
  3. 使用Random来确定下一个字符是字母还是数字。
  4. 再次使用Random生成字母或数字数组的索引(取决于您在步骤3中获得的数据)。 将获得的字符附加到密码。
  5. 从3开始重复,直到获得2中获得的字符数量。

这将是最简单的一个:)

 String char_group = "abcdefghijklmnopqrstuvwxyz"; String digit_group = "123456789"; // first choose a len of pwd Random ran = new Random(); int pwd_len = ran.nextInt(50); //50 is the max length of password,say // check that pwd_len is not less than 6 // do the check here // finally create the password.. StringBuffer pwd = new StringBuffer(); Random RNG = new Random(); for (int i = 0; i < pwd_len ; i++) { int randomNum = RNG.nextInt(100); char c = ''; // Here 25% is the ratio of mixing digits // in the password, you can change 4 to any // other value to change the depth of mix // or you can even make it random. if (randomNum % 4 == 0) { c = digit_group[randomNum % digit_group.length]; } else { c = char_group[randomNum % char_group.length]; } pwd.append(c); } return pwd.toString(); 

有点晚了,但我通常使用以下代码:

 private static final int PASSWORD_SIZE = 16; private static final String VALID_SPECIAL_CHARACTERS = "!@#$%&*()_-+=[]{}\\|:/?.,><"; // Note the double \ as escape private static String createPassword() { SecureRandom random = new SecureRandom(); StringBuilder password = new StringBuilder(); while (password.length() < PASSWORD_SIZE) { char character = (char) random.nextInt(Character.MAX_VALUE); if ((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9') || VALID_SPECIAL_CHARACTERS.contains(String.valueOf(character))) { password.append(character); } } return password.toString(); } 

无法保证密码中始终存在数字,特殊字符,小写字母和大写字符。 这可以通过首先添加字符和数字来强制执行,但是这会创建更可预测的密码。

以下是如何确保生成的密码符合您的密码标准,例如:在您的情况下,我会使用此正则表达式:

 String regex = "^(?=[a-zA-Z0-9ñÑ]*\d)(?=[a-zA-Z0-9ñÑ]*[az])(?=[a-zA-Z0-9ñÑ]*[AZ])[a-zA-Z0-9ñÑ]{6,}$" 

此正则表达式符合以下条件:

1.-至少1个lowerCase字母

2.-至少1个upperCase字母

3.-至少1位数(数字)

4.-至少6个字符(请注意,在正则表达式结尾处使用逗号后添加大于6的数字,现在将满足至少6个字符和最大值的标准)

 char[] char = {'a','b','c','d','e','f','g','h',...}; SecureRandom random = new SecureRandom(); StringBuffer password = new StringBuffer(); while(!password.toString().matches("your regex")){ for(int i = 0; i < 8; i++) { password.append(char [ random.nextInt(char .length) ]); } } System.out.println(password.toString()); 

这段代码的作用是, while您生成的密码不符合您的条件时,它会反复循环for循环。

实现了PasswordBuilder 。 支持passwrod限制,必须有字符和多少字符,字符范围和它们的列表。

用法示例:

 System.out.println(new PasswordBuilder().addCharsOption("!@#$%&*()_-+=[]{}\\|:/?.,><", 1).addRangeOption('A', 'Z', 1).addRangeOption('a', 'z', 0).addRangeOption('0', '9', 1).build()); 

示例结果: QU1GY7p+j+-PUW+_

 System.out.println(new PasswordBuilder().addCharsOption("!@#$%&*()_-+=[]{}\\|:/?.,><", 1).addRangeOption('A', 'Z', 1).addRangeOption('a', 'z', 0).addRangeOption('0', '9', 1).setSize(5).build()); 

示例结果: %,4NX

执行:

 //Version=1.0 //Source=https://www.dropbox.com/s/3a4uyrd2kcqdo28/PasswordBuilder.java?dl=0 //Dependencies=java:7 com.google.guava:guava:18.0 commons-lang:commons-lang:2.6 import com.google.common.primitives.Chars; import org.apache.commons.lang.ArrayUtils; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by alik on 5/26/16. */ public class PasswordBuilder { private int size = 16; private List options = new ArrayList<>(); private Map, Integer> musts = new java.util.LinkedHashMap<>(); private SecureRandom secureRandom = new SecureRandom(); public PasswordBuilder() { } public PasswordBuilder setSize(int size) { this.size = size; return this; } public PasswordBuilder addRangeOption(char from, char to, int mustCount) { List option = new ArrayList<>(to - from + 1); for (char i = from; i < to; ++i) { option.add(i); } return addOption(option, mustCount); } public PasswordBuilder addCharsOption(String chars, int mustCount) { return addOption(Chars.asList(chars.toCharArray()), mustCount); } public PasswordBuilder addOption(List option, int mustCount) { this.options.addAll(option); musts.put(option, mustCount); return this; } public String build() { validateMustsNotOverflowsSize(); Character[] password = new Character[size]; // Generate random from musts for (Map.Entry, Integer> entry : musts.entrySet()) { for (int i = 0; i < entry.getValue(); i++) { int charIndex = secureRandom.nextInt(entry.getKey().size()); char c = entry.getKey().get(charIndex); addChar(password, c); } } // Generate from overall for (int i = 0; i < password.length; i++) { if (password[i] != null) continue; password[i] = options.get(secureRandom.nextInt(options.size())); } return new String(ArrayUtils.toPrimitive(password)); } private void addChar(Character[] password, char c) { int i; for (i = secureRandom.nextInt(password.length); password[i] != null; i = secureRandom.nextInt(password.length)) { } password[i] = c; } private void validateMustsNotOverflowsSize() { int overallMusts = 0; for (Integer mustCount : musts.values()) { overallMusts += mustCount; } if (overallMusts > size) { throw new RuntimeException("Overall musts exceeds the requested size of the password."); } } public static void main(String[] args) { System.out.println(new PasswordBuilder().addCharsOption("!@#$%&*()_-+=[]{}\\|:/?.,><", 1).addRangeOption('A', 'Z', 1).addRangeOption('a', 'z', 0).addRangeOption('0', '9', 1).build()); System.out.println(new PasswordBuilder().addCharsOption("!@#$%&*()_-+=[]{}\\|:/?.,><", 1).addRangeOption('A', 'Z', 1).addRangeOption('a', 'z', 0).addRangeOption('0', '9', 1).setSize(5).build()); } }