我想每次都生成一个唯一的密码。我正在使用此代码生成密码。
import java.util.Random;
public class PasswordGenerator
{
public static String generatePassword()
{
Random r[] = new Random[8];
r[0] = new Random(1234567);
r[1] = new Random(7654321);
r[2] = new Random(-1234567);
r[3] = new Random(-7654321);
r[4] = new Random(5463721);
r[5] = new Random(2743615);
r[6] = new Random(-9753214);
r[7] = new Random(-3125769);
Random x = new Random(2325671);
StringBuilder password = new StringBuilder();
int length = x.nextInt(5)+9;
password.setLength(length);
for(int i=0;i<length;i++)
{
x.setSeed(r[i%8].nextInt(500)*r[4].nextInt(900));
password.setCharAt(i,(char)(r[x.nextInt(256)%8].nextInt(95)+32));
}
return password.toString();
}
}
调用generatePassword()
的代码(如果重要)
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == generate)
{
String userName = username.getText();
if(userName.isEmpty() || username == null)
{
JOptionPane.showMessageDialog(null,"username not entered\nFirst enter your username","ERROR",JOptionPane.ERROR_MESSAGE);
username.requestFocus();
username.selectAll();
return;
}
else if(userName.length() <=5)
{
JOptionPane.showMessageDialog(null,"Bad Username.\nUsername should be atleast six characters long.","ERROR",JOptionPane.ERROR_MESSAGE);
username.requestFocus();
username.selectAll();
return;
}
else
{
String passwd = PasswordGenerator.generatePassword();
password.setText(passwd);
return;
}
}
else if(event.getSource() == submit)
{
String passwordField = password.textField();
if(passwordField.isEmpty() || passwordField == null)
{
JOptionPane.showMessageDialog(null,"Please Generate your password first by clicking on the \"Generate\" button.",JOptionPane.ERROR_MESSAGE);
generate.requestFocus();
return;
}
else
{
//do something...
}
}
}
每次生成相同的密码,即使我重新编译它。我每次应该修改什么才能生成唯一的密码?
最后工作代码......
import java.util.Random;
public class PasswordGenerator
{
public static String generatePassword()
{
Random r[] = new Random[8];
for(int i=0;i<8;i++)
r[i] = new Random();
Random x = new Random();
StringBuilder password = new StringBuilder();
int length = x.nextInt(5)+9;
password.setLength(length);
for(int i=0;i<length;i++)
{
x.setSeed(r[i%8].nextInt(500)*r[4].nextInt(900));
password.setCharAt(i,(char)(r[x.nextInt(256)%8].nextInt(95)+32));
}
return password.toString();
}
}
特别感谢@reimeus和@Jon Skeet
答案 0 :(得分:9)
每次重新编译时都会生成相同的密码。我应该实际修改什么来每次生成一个唯一的密码?
你明确地为你的9个Random实例提供相同的种子:
Random r[] = new Random[8];
r[0] = new Random(1234567);
r[1] = new Random(7654321);
r[2] = new Random(-1234567);
r[3] = new Random(-7654321);
r[4] = new Random(5463721);
r[5] = new Random(2743615);
r[6] = new Random(-9753214);
r[7] = new Random(-3125769);
Random x = new Random(2325671);
不清楚为什么你甚至得到多个Random
的实例,但你不应该指定相同的种子 - 保证每次都会得到相同的结果。只使用不带种子的Random
构造函数,然后根据当前时间选择种子(现代版本中有一些jiggery-pokery,以避免在多次调用构造函数时使用相同的种子快速连续。)
看起来你正在做各种各样的“聪明”搞乱,试图让数据更随机 - 根据在不同实例上调用next
的结果设置一个种子,等等。使代码更难理解,但不再随意。您仍在使用具有确定性RNG的预定种子。那里没有变异的来源。
此外,对于敏感信息,您应使用SecureRandom
代替Random
。
答案 1 :(得分:2)
这是因为您使用固定的种子值实例化了Random instanced:
r [0] = new Random(1234567); ...
如果使用相同的种子创建了两个Random实例,并且为每个实例创建了相同的方法调用序列,则它们将生成并返回相同的数字序列。
答案 2 :(得分:2)
我建议您使用无参数随机构造函数来声明Random对象,因为带参数的对象设置种子,而种子又使随机对象成为原子。我在下面为您编写了一个示例,我将结果通过将密码长度设置为6来为密码返回6个字符。
import java.util.Random;
public class PasswordGenerator
{
public static String generatePassword()
{
Random r[] = new Random[8];
r[0] = new Random();
r[1] = new Random();
r[2] = new Random();
r[3] = new Random();
r[4] = new Random();
r[5] = new Random();
r[6] = new Random();
r[7] = new Random();
Random x = new Random();
StringBuilder password = new StringBuilder();
int length = 6;
password.setLength(length);
for(int i=0;i<length;i++)
{
x.setSeed(r[i%8].nextInt(500)*r[4].nextInt(900));
password.setCharAt(i,(char)(r[x.nextInt(256)%8].nextInt(95)+32));
}
return password.toString();
}
public static void main(String []args){
System.out.println(PasswordGenerator.generatePassword());
}
}
答案 3 :(得分:1)
怎么样:
r[0] = new Random(System.nanoTime());
时间值可能会为您提供良好的种子(=随机参数)。