可能重复:
创建唯一的 10 个字母数字字符串
我需要生成唯一的随机密码。
所以我想做类似的事情,MD5(counter+a_random_string+timeInMills)
但这有 32 个字符的输出。
我需要一个 8 个字符的密码。
如何生成唯一的自定义长度的人类可读密码?
更新:
我每次生成 N 个(少于 30 个)密码,我需要这些 N 个密码是非冗余的。对独特性的需求不是绝对的。还检查生成的密码是否有重复值并重新生成它可能会导致无限循环
可能重复:
创建唯一的 10 个字母数字字符串
我需要生成唯一的随机密码。
所以我想做类似的事情,MD5(counter+a_random_string+timeInMills)
但这有 32 个字符的输出。
我需要一个 8 个字符的密码。
如何生成唯一的自定义长度的人类可读密码?
更新:
我每次生成 N 个(少于 30 个)密码,我需要这些 N 个密码是非冗余的。对独特性的需求不是绝对的。还检查生成的密码是否有重复值并重新生成它可能会导致无限循环
这是一个想法:使用java.util.UUID
类。
UUID 类提供了一个静态工厂方法来生成伪随机生成的 UUID。
您可以将 UUID 转换为字符串。
不要忘记,如果你想保证唯一性,你不能截断/子串 UUID 的值:
MSDN 上的文章:GUID 是全局唯一的,但 GUID 的子字符串不是.
假设字母表由大写/小写、数字和 32 个特殊字符(总共 98 个)组成,则有 98 8个可能性或大约 8.5x10 15。如果您想要“唯一”随机密码,因为您不会在没有首先用尽所有可能性的情况下两次生成相同的密码,那么只有两种选择:
第二种选择不太安全,因为如果有人确定算法,那么他们可以在给定一个密码的情况下预测下一个密码(和整个序列)。
保证随机生成的字符串唯一性的蛮力方法是存储所有字符串并在碰撞时重新生成:
protected Collection<String> generatedPasswords = new HashSet<String>();
public String generatePassword(int length) {
String password = null;
do {
StringBuilder buf = new StringBuilder();
// Append "length" random password characters to "buf".
password = buf.toString();
} while (this.generatedPasswords.contains(password));
return password;
}
但是,如果您只是想为最终用户生成“合理的”随机密码,并且偶尔(非常罕见)的冲突可以接受,那么您可以简单地获取 MD5 方案的前 N 个字符。
我为我创建了一个随机字符串/密码生成器程序,希望这也对你有用。
public class RandomStringGenerator{
private static int randomStringLength = 25 ;
private static boolean allowSpecialCharacters = true ;
private static String specialCharacters = "!@$%*-_+:";
private static boolean allowDuplicates = false ;
private static boolean isAlphanum = false;
private static boolean isNumeric = false;
private static boolean isAlpha = false;
private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
private static boolean mixCase = false;
private static final String capAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String num = "0123456789";
public static String getRandomString() {
String returnVal = "";
int specialCharactersCount = 0;
int maxspecialCharacters = randomStringLength/4;
try {
StringBuffer values = buildList();
for (int inx = 0; inx < randomStringLength; inx++) {
int selChar = (int) (Math.random() * (values.length() - 1));
if (allowSpecialCharacters)
{
if (specialCharacters.indexOf("" + values.charAt(selChar)) > -1)
{
specialCharactersCount ++;
if (specialCharactersCount > maxspecialCharacters)
{
while (specialCharacters.indexOf("" + values.charAt(selChar)) != -1)
{
selChar = (int) (Math.random() * (values.length() - 1));
}
}
}
}
returnVal += values.charAt(selChar);
if (!allowDuplicates) {
values.deleteCharAt(selChar);
}
}
} catch (Exception e) {
returnVal = "Error While Processing Values";
}
return returnVal;
}
private static StringBuffer buildList() {
StringBuffer list = new StringBuffer(0);
if (isNumeric || isAlphanum) {
list.append(num);
}
if (isAlpha || isAlphanum) {
list.append(alphabet);
if (mixCase) {
list.append(capAlpha);
}
}
if (allowSpecialCharacters)
{
list.append(specialCharacters);
}
int currLen = list.length();
String returnVal = "";
for (int inx = 0; inx < currLen; inx++) {
int selChar = (int) (Math.random() * (list.length() - 1));
returnVal += list.charAt(selChar);
list.deleteCharAt(selChar);
}
list = new StringBuffer(returnVal);
return list;
}
}
创建一个 char 数组并用随机字母填充它。
Random r = new Random();
char[] pass = new char[8];
for (int i = 0; i < pass.length; ++i)
{
pass[i] = r.nextInt(26) + 'a';
}
String passStr = new String(pass);
您可以使用任何简单的算法生成随机字符串(例如,请参阅解决方案:How do I create a random alpha-numeric string in C++?)。然后您可以做的是保留一个 Set(或任何其他可以确保唯一性的数据结构)并继续将这些随机字符串插入其中,一旦达到您所需的限制,您就可以返回 Set。由于您需要的字符串数量非常少(~50),碰撞的机会也非常非常小,所以它应该非常有效。