为什么我的密码生成代码无法按预期工作?

cyb*_*e92 2 java random password-generator

我想每次生成一个唯一的密码.我正在使用此代码生成密码.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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...
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

每次生成相同的密码,即使我重新编译它.我应该实际修改什么来每次生成一个唯一的密码?

最后工作代码......

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

特别感谢@reimeus和@Jon Skeet

Jon*_*eet 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);
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚为什么你甚至多个实例Random,但你不应该指定相同的种子 - 这将保证你每次都得到相同的结果.只需使用Random不接受种子的构造函数,然后根据当前时间选择一个种子(现代版本中有一些jiggery-pokery,以避免在快速连续多次调用构造函数时使用相同的种子.)

看起来你正在做各种各样的"聪明"搞乱,试图让数据更随机 - 根据调用next不同实例的结果设置一个种子,等等.你已经使代码更难理解了,但不是随机的.您仍在使用具有确定性RNG的预定种子.那里没有变异的来源.

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