为什么我的密码生成代码不能按预期工作



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

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 enterednFirst 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

每次它都会生成相同的密码,即使我重新编译了它。我应该修改什么才能每次生成唯一的密码?

您正在显式地为您的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构造函数,它将根据当前时间选择种子(在现代版本中,如果您连续多次快速调用构造函数,则会使用一些小技巧来避免使用同一种子。)

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

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

这是因为您使用固定的种子值实例化了Random实例:

r[0]=新随机数(1234567);…

来自Random JavaDoc:

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

我建议您使用无参数随机构造函数来声明随机对象,因为接受参数的构造函数会设置种子,从而使随机对象成为原子。我在下面为您写了一个例子,通过将密码长度设置为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());
}
}

关于:

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

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

相关内容

  • 没有找到相关文章