2013-07-02 71 views
2

我想每次都生成一个唯一的密码。我正在使用此代码来生成密码。为什么我的密码生成代码不能按预期工作?

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和@乔恩飞碟双向

回答

9

每次生成,即使我重新编译相同的密码的时间。我应该怎样修改每次生成一个唯一的密码?

明确提供相同的种子每一个随机的您9个实例:

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多个实例,但你不应该指定相同的种子 - 保证你每次都得到相同的结果。只需使用不带种子的构造函数,并且会根据当前时间选择一个种子(在现代版本中使用一些jiggery-pokery来避免使用相同的种子,如果连续多次调用构造函数。 )

看起来你正在做各种“巧妙”的搞乱尝试使数据更随机 - 根据在不同实例上调用next的结果设置一个种子等。使代码更难理解,但没有更多的随机。你仍然使用预定的种子和确定性的RNG。那里没有变化的来源。

此外,对于敏感信息,您应该使用SecureRandom而不是Random

+0

好了解。感谢您的帮助,现在它正在工作。 – cyberpirate92

+0

嗯SecureRandom ...好吧,我会记住,再次感谢 – cyberpirate92

2

这是因为你的实例实例化随机与固定种子值:

R [0] =新的随机(1234567); ...

Random JavaDoc来自:

如果随机的两个实例使用相同的种子创建,并且方法的相同序列调用为每个制成,它们将生成并返回相同的序列数字。

1

什么:

r[0] = new Random(System.nanoTime()); 

的时间价值可能会给你一个很好的种子(=参数随机)。

2

我建议你使用no参数的随机构造函数来声明你的Random对象,因为需要参数的那个对象设置种子,从而使得随机对象成为原子。我已经在下面为您编写了一个示例,并且通过将密码长度设置为六来让结果返回您的密码的完全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()); 
} 
} 
相关问题