Генератор случайных паролей, возвращающий неправильные символы - Java - PullRequest
2 голосов
/ 04 ноября 2019

В настоящее время я использую следующий код для генерации случайного пароля:

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 (пример: &% Â & $ & # £% # Â &)

1 Ответ

8 голосов
/ 04 ноября 2019

Ваш вставленный код не содержит ошибок и должен делать именно то, что вы хотите.

Тем не менее, это почти 100%, безусловно, должно быть проблемой кодировки символов.

Все символы вВаша действительная строка, за исключением символа фунта, находится в диапазоне ASCII 32-127, и почти во всех существующих кодировках символов это просто работает (строка "foo", если она закодирована в байтах с использованием ASCII итогда декодирование с помощью UTF-8, или ISO-8859-1, или Win CP252, или просто чего-то еще, все еще "foo") - но этот фунт - нет. Если вы возьмете строку «Это будет 5 фунтов стерлингов - пожалуйста!», Закодируйте ее в байтах, скажем, ISO-8859-1, а затем декодируйте ее обратно в строку, используя UTF-8, вы получите »Это будет 5, - пожалуйста! ".

Итак, на минуту теоретизируем, что эта строка кодируется с использованием одной кодировки кодировки, а затем декодируется с использованием другой, это ваша ошибка, но эта ошибка победила. Это не имеет никакого эффекта, пока все символы, которые вы выбрасываете в этом ошибочном процессе, находятся в диапазоне 32-127 в таблице ASCII.

Таким образом, у вас есть 2 способа решения этой проблемы. Это исправит любой из них:

  1. Убедитесь, что список допустимых символов содержит только 32-127 символов ASCII. Например, удалите фунт, сделайте его минусом, подчеркиванием или открытыми скобками.

  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 хорош, потому что API Файлов, в отличие от большинства других мест в библиотеках ядра Java, определен как всегда с UTF-8 как кодировка (тогда как другие местаиспользуйте «стандартное значение платформы», что бы это ни было, обычно это плохой выбор), и варианты 2 и 3 хороши, потому что вы явно используете UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...