随机密码生成器返回错误字符-Java

gio*_*rea 2 java random passwords generator

我目前正在使用以下代码生成随机密码:

static public String randomPasswordGenerator(int n, String valid) 
{ 
      char[] pwd = new char[n];
      Random rnd = new Random();
      for (int i = 0; i < pwd.length; i++)
      {
        pwd[i] = valid.charAt(rnd.nextInt(valid.length()));
      }
      return new String(pwd);
}
Run Code Online (Sandbox Code Playgroud)

当前有效参数设置为:

String valid = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789#$&%£";
Run Code Online (Sandbox Code Playgroud)

有时,当我生成密码时,会发现正在生成奇怪的字符,例如,我可以得到:n9iB8Qj6inR(其中,最后一个字符不包含在有效集中)

知道为什么会这样吗?

非常感谢

编辑我虽然这与编码问题有关,但是在调试上述函数的返回字符串时,我可以直接看到那个奇怪的字符。另外,使用字符集作为“#$&%£”有时会返回所有字符以及那个奇怪的A(例如:&%Â&$&#£%#Â&)

rzw*_*oot 8

您粘贴的代码没有错误,应该准确地完成您想要的操作。

但是,这几乎100%肯定是字符编码问题。

有效字符串中的所有字符(井号除外)都在ASCII范围内32-127,并且在几乎所有现有的字符编码中,这些字符都可以正常工作(如果使用ASCII编码为字节,然后使用UTF-8或ISO-8859-1或Win CP252或几乎其他任何东西,仍然是“ foo”),但实际上不是。如果您使用字符串“那将是5英镑,请!”,使用例如ISO-8859-1将其编码为字节,然后使用UTF-8将其解码回字符串,则会得到“那将是5,请!”。

因此,暂时将这个字符串用一种字符集编码进行编码,然后再用另一种字符集进行解码,这就是您的错误,但是,只要您通过该错误处理过程所抛出的字符是正确的,该错误就不会起作用。全部在ASCII表上的32-127范围内。

因此,您有两种方法可以解决此问题。要么将其修复:

  1. 确保有效字符列表仅包含ASCII 32-127字符。例如,删除磅,使其为负号,下划线或圆括号。

  2. 找到将字符串编码为字节(反之亦然)的位置,并确保始终明确说明正在使用的编码。然后,我强烈建议您明确实施UTF-8。例如:

坏:

new FileReader(new File("/path/to/a/file"))
byte[] bytes = .... some bytes ...; String x = new String(bytes);
Run Code Online (Sandbox Code Playgroud)

好:

Files.newBufferedReader(Paths.get("/path/to/a/file")) // case 1
new BufferedReader(new InputStreamReader(new FileInputStream(new File("/path/to/a/file")), StandardCharsets.UTF_8)); // case 2
byte[] bytes = .... some bytes ...; String x = new String(bytes, StandardCharsets.UTF_8);
Run Code Online (Sandbox Code Playgroud)

尽管在所有这些情况下都应注意,但您应该使用try-with-resources正确关闭它们。

情况1很好,因为与Java核心libs中的大多数其他地方不同,Files API被定义为始终使用UTF-8作为编码(而其他地方通常使用“平台默认值”,无论可能是什么)一个不好的选择),情况2和3很好,因为您显式地使用UTF-8。