2013-07-02 3 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:

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.

+0

Ok понял. Спасибо за помощь вам обоим, теперь это работает. – cyberpirate92

+0

hmmm SecureRandom ... ok, я буду помнить это, спасибо снова – cyberpirate92

2

Это потому, что вы инстанцирован ваш случайный инстанс с фиксированным начальным значением:

г [0] = новый Random (1234567); ...

От Random JavaDoc:

Если два экземпляра Random создаются с той же семени, и та же последовательность вызовов метода производится для каждого, они будут генерировать и возвращать одинаковые последовательности чисел.

1

насчет:

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

Значение времени может дать вам хорошее семя (= параметр для Random).

2

Я предлагаю вам использовать случайный конструктор без аргументов, чтобы объявлять ваши объекты 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()); 
} 
} 
Смежные вопросы