2013-07-02 94 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()); 
} 
}