【问题标题】:Random password generator returning wrong characters - java随机密码生成器返回错误字符 - java
【发布时间】:2020-02-29 16:18:03
【问题描述】:

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

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);
}

有效参数当前设置为:

String valid = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789#$&%£";

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

知道为什么会这样吗?

非常感谢

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

【问题讨论】:

  • 以上代码至少没有明显的bug。可能是打印密码的时候出了问题?
  • £ 不是ASCII 符号。我只能假设它用多个代码点表示,并将其转换为 char 仅返回第一个代码点。但这只是在黑暗中刺伤。尝试输出随机索引并将其与密码中的错误字符进行比较。如果它与£ 的索引匹配,你就知道这可能是问题
  • 尝试存储(随机)索引并在遇到错误密码时打印它们。这样您就可以将其追踪到特定的随机值。
  • @QBrute 使用 valid = "£" 和 n = 1 运行 OP 的代码,按预期返回 "£"。我认为这不是错误的原因。
  • @mario_sunny 啊,我明白了。可能是因为£ 包含在扩展ASCII 表中?

标签: java random passwords generator


【解决方案1】:

您粘贴的代码没有错误,应该完全按照您的意愿行事。

尽管如此,这几乎 100% 肯定是字符编码问题。

您的有效字符串中的所有字符,除了磅符号,都在 32-127 的 ASCII 范围内,并且在几乎所有存在的字符编码中,这些都可以正常工作(字符串“foo”如果使用 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);

好:

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);

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

案例 1 很好,因为与 java 核心库中的大多数其他地方不同,Files API 被定义为始终使用 UTF-8 作为编码(而其他地方使用“平台默认值”,无论这可能是,通常是一个糟糕的选择),而案例 2 和 3 是好的,因为您明确使用 UTF-8。

【讨论】:

  • 谢谢。我确实尝试将其编码为 UTF-8,没有任何改变,所以问题出在其他地方。非常感谢,因为这是一个非常好的答案
猜你喜欢
  • 2020-05-11
  • 2022-09-23
  • 2021-04-14
  • 1970-01-01
  • 2016-02-16
  • 2012-11-06
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多