Как сгенерировать случайную буквенно-цифровую строку?

StackOverflow https://stackoverflow.com/questions/41107

Вопрос

Я так долго искал простой Java-алгоритм для генерации псевдослучайной буквенно-цифровой строки.В моей ситуации он использовался бы как уникальный идентификатор сеанса / ключа, который, "вероятно", был бы уникальным в течение 500K+ генерация (мои потребности на самом деле не требуют ничего более сложного).

В идеале я мог бы указать длину в зависимости от моих потребностей в уникальности.Например, сгенерированная строка длиной 12 может выглядеть примерно так "AEYGF7K0DM1X".

Это было полезно?

Решение

Алгоритм

Чтобы сгенерировать случайную строку, объедините символы, нарисованные случайным образом из набора допустимых символов, до тех пор, пока строка не достигнет желаемой длины.

Реализация

Вот несколько довольно простых и очень гибких кодов для генерации случайных идентификаторов. Прочтите следующую информацию для ознакомления с важными примечаниями по применению.

import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;

public class RandomString {

    /**
     * Generate a random string.
     */
    public String nextString() {
        for (int idx = 0; idx < buf.length; ++idx)
            buf[idx] = symbols[random.nextInt(symbols.length)];
        return new String(buf);
    }

    public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static final String lower = upper.toLowerCase(Locale.ROOT);

    public static final String digits = "0123456789";

    public static final String alphanum = upper + lower + digits;

    private final Random random;

    private final char[] symbols;

    private final char[] buf;

    public RandomString(int length, Random random, String symbols) {
        if (length < 1) throw new IllegalArgumentException();
        if (symbols.length() < 2) throw new IllegalArgumentException();
        this.random = Objects.requireNonNull(random);
        this.symbols = symbols.toCharArray();
        this.buf = new char[length];
    }

    /**
     * Create an alphanumeric string generator.
     */
    public RandomString(int length, Random random) {
        this(length, random, alphanum);
    }

    /**
     * Create an alphanumeric strings from a secure generator.
     */
    public RandomString(int length) {
        this(length, new SecureRandom());
    }

    /**
     * Create session identifiers.
     */
    public RandomString() {
        this(21);
    }

}

Примеры использования

Создайте небезопасный генератор для 8-символьных идентификаторов:

RandomString gen = new RandomString(8, ThreadLocalRandom.current());

Создайте безопасный генератор для идентификаторов сеансов:

RandomString session = new RandomString();

Создайте генератор с легко читаемыми кодами для печати. Строки длиннее буквенно-цифровых строк, чтобы компенсировать использование меньшего количества символов:

String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);

Использовать как идентификаторы сеанса

Генерировать идентификаторы сеанса, которые могут быть уникальными, недостаточно, или вы можете просто использовать простой счетчик. Злоумышленники перехватывают сеансы, когда используются предсказуемые идентификаторы.

Между длиной и безопасностью существует напряженность. Более короткие идентификаторы легче угадать, потому что возможностей меньше. Но более длинные идентификаторы потребляют больше памяти и пропускной способности. Помогает больший набор символов, но он может вызвать проблемы с кодировкой, если идентификаторы включены в URL-адреса или введены вручную.

Основной источник случайности или энтропии для идентификаторов сеансов должен исходить от генератора случайных чисел, предназначенного для криптографии. Однако инициализация этих генераторов иногда может быть вычислительно дорогой или медленной, поэтому следует предпринять усилия для их повторного использования, когда это возможно.

Использовать в качестве идентификаторов объектов

Не каждое приложение требует безопасности. Случайное назначение может быть эффективным способом для нескольких объектов генерировать идентификаторы в совместно используемом пространстве без какой-либо координации или разделения. Координация может быть медленной, особенно в кластерной или распределенной среде, а разделение пространства вызывает проблемы, когда у сущностей возникают слишком маленькие или слишком большие доли.

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

Необходимо также позаботиться о том, чтобы использовать идентификаторы, достаточно длинные, чтобы сделать коллизии маловероятными, учитывая ожидаемое общее количество идентификаторов. Это называется «парадоксом дня рождения». Вероятность столкновения, p , составляет приблизительно n < sup> 2 / (2q x ), где n - число фактически сгенерированных идентификаторов, q - число различных символы в алфавите, а x - длина идентификаторов. Это должно быть очень маленькое число, например 2 ‑50 или меньше.

Работа над этим показывает, что вероятность столкновения между 500k 15-символьными идентификаторами составляет около 2 ‑52 , что, вероятно, менее вероятно, чем необнаруженные ошибки космических лучей и т. д.

Сравнение с UUID

Согласно их спецификации, UUID не должны быть непредсказуемыми, и не следует использовать в качестве идентификаторов сеансов.

UUID в их стандартном формате занимают много места: 36 символов только для 122 бит энтропии. (Не все биты «случайного» UUID выбираются случайным образом.) Случайно выбранная буквенно-цифровая строка упаковывает больше энтропии всего в 21 символ.

UUID не являются гибкими; они имеют стандартизированную структуру и расположение. Это их главное достоинство, а также их главная слабость. При сотрудничестве с внешней стороной может оказаться полезной стандартизация, предлагаемая UUID. Для чисто внутреннего использования они могут быть неэффективными.

Другие советы

Java предоставляет способ сделать это напрямую.Если вам не нужны черточки, их легко удалить.Просто используй uuid.replace("-", "")

import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}

Выходной сигнал:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();

String randomString( int len ){
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}

Если вы с удовольствием используете классы Apache, вы могли бы использовать org.apache.commons.text.RandomStringGenerator (текст на всеобщее обозрение).

Пример:

RandomStringGenerator randomStringGenerator =
        new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
                .build();
randomStringGenerator.generate(12); // toUpperCase() if you want

Начиная с commons-lang 3.6, RandomStringUtils устарел.

В одной строке:

Long.toHexString(Double.doubleToLongBits(Math.random()));
  

http://mynotes.wordpress.com/2009 / 07/23 / Java-генерирующей-случайная строка /

Для этого вы можете использовать библиотеку Apache: RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

Это легко достижимо без каких-либо внешних библиотек.

1.Криптографическая Генерация Псевдослучайных данных

Сначала вам нужен криптографический PRNG.Java имеет SecureRandom для этого обычно используется наилучший источник энтропии на компьютере (например /dev/random) . Подробнее читайте здесь.

SecureRandom rnd = new SecureRandom();
byte[] token = new byte[byteLength];
rnd.nextBytes(token);

Примечание: SecureRandom это самый медленный, но наиболее безопасный способ генерации случайных байтов в Java.Однако я рекомендую НЕ рассматривать здесь производительность, поскольку обычно она не оказывает реального влияния на ваше приложение, если только вам не приходится генерировать миллионы токенов в секунду.

2.Требуемое пространство возможных значений

Далее вы должны решить, "насколько уникальным" должен быть ваш токен.Весь и единственный смысл рассмотрения энтропии состоит в том, чтобы убедиться, что система может противостоять атакам методом грубой силы:пространство возможных значений должно быть настолько большим, чтобы любой злоумышленник мог попробовать лишь незначительную часть значений за несмешное время1.Уникальные идентификаторы, такие как random UUID иметь 122 бита энтропии (т.е.2 ^ 122 = 5.3x10 ^ 36) - вероятность столкновения равна "*(...) для того, чтобы вероятность дублирования составляла один шанс из миллиарда, необходимо сгенерировать 103 триллиона UUID версии 42". Мы выберем 128 бит, так как он ровно умещается в 16 байтах и рассматривается как в высшей степени достаточный за то, что он уникален практически для всех, кроме самых экстремальных, вариантов использования, и вам не нужно думать о дубликатах.Вот простая сравнительная таблица энтропии, включающая простой анализ проблема с днем рождения.

comparison of token sizes

Для простых требований может быть достаточно длины в 8 или 12 байт, но с 16 байтами вы находитесь на "безопасной стороне".

И это, в принципе, все.Последнее, что нужно сделать, это подумать о кодировке, чтобы ее можно было представить в виде текста для печати (читай, String).

3.Двоичная кодировка в Текст

Типичные кодировки включают:

  • Base64 каждый символ кодирует 6 бит, создавая накладные расходы в размере 33%.К счастью, существуют стандартные реализации в Java 8+ и Android.С более старой Java вы можете использовать любой из многочисленные сторонние библиотеки.Если вы хотите, чтобы ваши токены были безопасны по URL, используйте url-адрес-безопасный версия RFC4648 (которая обычно поддерживается большинством реализаций).Пример кодирования 16 байт с заполнением: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 каждый символ кодирует 5 бит, создавая 40% накладных расходов.Это позволит использовать A-Z и 2-7 что делает его достаточно компактным, не чувствительным к регистру буквенно-цифровых символов.Там нет никакого стандартная реализация в JDK.Пример кодирования 16 байт без заполнения: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (шестнадцатеричный) каждый символ кодирует 4 бита, требуя 2 символа на байт (т.е.16 байт создают строку длиной 32).Следовательно, hex менее экономичен в использовании пространства, чем Base32 но безопасен в использовании в большинстве случаев (url), поскольку он использует только 0-9 и A Для F.Пример кодировки 16 байт: 4fa3dd0f57cb3bf331441ed285b27735. Смотрите обсуждение SO о преобразовании в hex здесь.

Дополнительные кодировки, такие как База 85 и экзотика База 122 существуют с лучшей / худшей эффективностью использования пространства.Вы можете создать свою собственную кодировку (что в основном и делает большинство ответов в этой теме), но я бы не советовал этого делать, если у вас нет очень специфических требований.Видишь подробнее о схемах кодирования читайте в статье Википедии.

4.Краткое изложение и пример

  • Использование SecureRandom
  • Используйте не менее 16 байт (2 ^ 128) возможных значений
  • Кодируйте в соответствии с вашими требованиями (обычно hex или base32 если вам нужно, чтобы оно было буквенно-цифровым)

Не надо

  • ...используйте кодировку вашего домашнего напитка: лучше обслуживается и читается для других, если они видят, какую стандартную кодировку вы используете вместо странных циклов for, создающих символы за раз.
  • ...использовать UUID: у него нет никаких гарантий случайности;вы тратите впустую 6 бит энтропии и имеете подробное строковое представление

Пример:Генератор Шестнадцатеричных Токенов

public static String generateRandomHexToken(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return new BigInteger(1, token).toString(16); //hex encoding
}

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

Пример:Генератор токенов Base64 (безопасный URL)

public static String generateRandomBase64Token(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding
}

//generateRandomBase64Token(16) -> EEcCCAYuUcQk7IuzdaPzrg

Пример:Инструмент Java CLI

Если вам нужен готовый к использованию инструмент cli, вы можете использовать dice: https://github.com/patrickfav/dice

использование доллара должно быть простым, как:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

выводит что-то подобное:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

Вот это на Java:

import static java.lang.Math.round;
import static java.lang.Math.random;
import static java.lang.Math.pow;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static org.apache.commons.lang.StringUtils.leftPad

public class RandomAlphaNum {
  public static String gen(int length) {
    StringBuffer sb = new StringBuffer();
    for (int i = length; i > 0; i -= 12) {
      int n = min(12, abs(i));
      sb.append(leftPad(Long.toString(round(random() * pow(36, n)), 36), n, '0'));
    }
    return sb.toString();
  }
}

Вот пример прогона:

scala> RandomAlphaNum.gen(42)
res3: java.lang.String = uja6snx21bswf9t89s00bxssu8g6qlu16ffzqaxxoy

Удивительно, что никто здесь этого не предложил, но:

import java.util.UUID

UUID.randomUUID().toString();

Легко.

Преимущество этого в том, что UUID красивы и длинны, и гарантированно их практически невозможно столкнуть.

В Википедии есть хорошее объяснение этому:

" ...только после генерации 1 миллиарда UUID каждую секунду в течение следующих 100 лет вероятность создания только одного дубликата составит около 50% ".

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

Первые 4 бита - это тип версии и 2 для варианта, так что вы получаете 122 бита случайного значения.Так что, если вы хотеть to вы можете обрезать с конца, чтобы уменьшить размер UUID.Это не рекомендуется, но у вас все еще есть масса случайностей, достаточных для того, чтобы легко создавать 500 тысяч записей.

Краткое и простое решение, но с использованием только строчных и цифровых символов:

Random r = new java.util.Random ();
String s = Long.toString (r.nextLong () & Long.MAX_VALUE, 36);

Размер составляет около 12 цифр для базы 36 и не может быть улучшен таким образом. Конечно, вы можете добавить несколько экземпляров.

Альтернатива в Java 8:

static final Random random = new Random(); // Or SecureRandom
static final int startChar = (int) '!';
static final int endChar = (int) '~';

static String randomString(final int maxLength) {
  final int length = random.nextInt(maxLength + 1);
  return random.ints(length, startChar, endChar + 1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}
public static String generateSessionKey(int length){
String alphabet = 
        new String("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); //9
int n = alphabet.length(); //10

String result = new String(); 
Random r = new Random(); //11

for (int i=0; i<length; i++) //12
    result = result + alphabet.charAt(r.nextInt(n)); //13

return result;
}

Использование UUID небезопасно, потому что части UUID вообще не случайны. Процедура @erickson очень аккуратна, но не создает строки одинаковой длины. Следующего фрагмента должно быть достаточно:

/*
 * The random generator used by this class to create random keys.
 * In a holder class to defer initialization until needed.
 */
private static class RandomHolder {
    static final Random random = new SecureRandom();
    public static String randomKey(int length) {
        return String.format("%"+length+"s", new BigInteger(length*5/*base 32,2^5*/, random)
            .toString(32)).replace('\u0020', '0');
    }
}

Почему стоит выбрать length * 5 . Давайте предположим простой случай случайной строки длиной 1, поэтому один случайный символ. Чтобы получить случайный символ, содержащий все цифры 0-9 и символы a-z, нам понадобится случайное число от 0 до 35, чтобы получить по одному каждому символу. BigInteger предоставляет конструктор для генерации случайного числа, равномерно распределенного по диапазону от 0 до (2 ^ numBits - 1) . К сожалению, 35 - это не число, которое может быть получено 2 ^ numBits - 1. Таким образом, у нас есть два варианта: либо пойти с 2 ^ 5-1 = 31 или 2 ^ 6-1 = 63 . Если бы мы выбрали 2 ^ 6 , мы бы получили много «ненужных». / "длиннее" номера. Поэтому 2 ^ 5 - лучший вариант, даже если мы потеряем 4 символа (w-z). Чтобы сгенерировать строку определенной длины, мы можем просто использовать число 2 ^ (length * numBits) -1 . Последняя проблема: если нам нужна строка определенной длины, случайное число может сгенерировать небольшое число, поэтому длина не будет достигнута, поэтому мы должны дополнить строку требуемой длиной, добавляя нули.

import java.util.Random;

public class passGen{
    //Verison 1.0
    private static final String dCase = "abcdefghijklmnopqrstuvwxyz";
    private static final String uCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String sChar = "!@#$%^&*";
    private static final String intChar = "0123456789";
    private static Random r = new Random();
    private static String pass = "";

    public static void main (String[] args) {
        System.out.println ("Generating pass...");
        while (pass.length () != 16){
            int rPick = r.nextInt(4);
            if (rPick == 0){
                int spot = r.nextInt(25);
                pass += dCase.charAt(spot);
            } else if (rPick == 1) {
                int spot = r.nextInt (25);
                pass += uCase.charAt(spot);
            } else if (rPick == 2) {
                int spot = r.nextInt (7);
                pass += sChar.charAt(spot);
            } else if (rPick == 3){
                int spot = r.nextInt (9);
                pass += intChar.charAt (spot);
            }
        }
        System.out.println ("Generated Pass: " + pass);
    }
}

Итак, это просто добавляет пароль в строку и ... да, хорошо работает, проверь это ... очень просто. Я написал это

Я нашел это решение, которое генерирует случайную строку в шестнадцатеричном формате. Предоставленный модульный тест, кажется, соответствует моему основному варианту использования. Хотя это немного сложнее, чем некоторые другие ответы.

/**
 * Generate a random hex encoded string token of the specified length
 *  
 * @param length
 * @return random hex string
 */
public static synchronized String generateUniqueToken(Integer length){ 
    byte random[] = new byte[length];
    Random randomGenerator = new Random();
    StringBuffer buffer = new StringBuffer();

    randomGenerator.nextBytes(random);

    for (int j = 0; j < random.length; j++) {
        byte b1 = (byte) ((random[j] & 0xf0) >> 4);
        byte b2 = (byte) (random[j] & 0x0f);
        if (b1 < 10)
            buffer.append((char) ('0' + b1));
        else
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
        else
            buffer.append((char) ('A' + (b2 - 10)));
    }
    return (buffer.toString());
}

@Test
public void testGenerateUniqueToken(){
    Set set = new HashSet();
    String token = null;
    int size = 16;

    /* Seems like we should be able to generate 500K tokens 
     * without a duplicate 
     */
    for (int i=0; i<500000; i++){
        token = Utility.generateUniqueToken(size);

        if (token.length() != size * 2){
            fail("Incorrect length");
        } else if (set.contains(token)) {
            fail("Duplicate token generated");
        } else{
            set.add(token);
        }
    }
}
import java.util.Date;
import java.util.Random;

public class RandomGenerator {

  private static Random random = new Random((new Date()).getTime());

    public static String generateRandomString(int length) {
      char[] values = {'a','b','c','d','e','f','g','h','i','j',
               'k','l','m','n','o','p','q','r','s','t',
               'u','v','w','x','y','z','0','1','2','3',
               '4','5','6','7','8','9'};

      String out = "";

      for (int i=0;i<length;i++) {
          int idx=random.nextInt(values.length);
          out += values[idx];
      }
      return out;
    }
}
import java.util.*;
import javax.swing.*;
public class alphanumeric{
    public static void main(String args[]){
        String nval,lenval;
        int n,len;

        nval=JOptionPane.showInputDialog("Enter number of codes you require : ");
        n=Integer.parseInt(nval);

        lenval=JOptionPane.showInputDialog("Enter code length you require : ");
        len=Integer.parseInt(lenval);

        find(n,len);

    }
    public static void find(int n,int length) {
        String str1="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb=new StringBuilder(length);
        Random r = new Random();

        System.out.println("\n\t Unique codes are \n\n");
        for(int i=0;i<n;i++){
            for(int j=0;j<length;j++){
                sb.append(str1.charAt(r.nextInt(str1.length())));
            }
            System.out.println("  "+sb.toString());
            sb.delete(0,length);
        }
    }
}
  1. Измените символы строки в соответствии с вашими требованиями.

  2. Строка является неизменяемой.Здесь StringBuilder.append это более эффективно, чем конкатенация строк.


public static String getRandomString(int length) {
       final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+";
       StringBuilder result = new StringBuilder();
       while(length > 0) {
           Random rand = new Random();
           result.append(characters.charAt(rand.nextInt(characters.length())));
           length--;
       }
       return result.toString();
    }

Мне не нравится ни один из ответов, касающихся " простого " решение: S

Я бы пошел на простой;), чистый java, один вкладыш (энтропия основана на произвольной длине строки и заданном наборе символов):

public String randomString(int length, String characterSet) {
    return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));//charachterSet can basically be anything
    }
}

или (немного более читабельный старый способ)

public String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
        int randomInt = new SecureRandom().nextInt(characterSet.length());
        sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //charachterSet can basically be anything
    }
}

Но, с другой стороны, вы также можете использовать UUID с довольно хорошей энтропией ( https: //en.wikipedia.org/wiki/Universally_unique_identifier#Collisions ):

UUID.randomUUID().toString().replace("-", "")

Надеюсь, это поможет.

Вы упоминаете «простой», но на всякий случай, если кто-то еще ищет что-то, отвечающее более строгим требованиям безопасности, вы можете взглянуть на jpwgen . jpwgen смоделирован после pwgen в Unix и очень легко настраивается.

Вот решение Scala:

(for (i <- 0 until rnd.nextInt(64)) yield { 
  ('0' + rnd.nextInt(64)).asInstanceOf[Char] 
}) mkString("")

Вы можете использовать класс UUID с его сообщением getLeastSignificantBits (), чтобы получить 64-битные данные Random, а затем преобразовать их в число с основанием 36 (то есть строку, состоящую из 0-9, A-Z):

Long.toString(Math.abs( UUID.randomUUID().getLeastSignificantBits(), 36));

В результате получается строка длиной до 13 символов. Мы используем Math.abs (), чтобы убедиться, что в нем нет пробивающегося знака минуса.

Вы можете использовать следующий код, если ваш пароль обязательно содержит цифры буквенных специальных символов:

private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;

public static String getRandomPassword() {
    StringBuilder password = new StringBuilder();
    int j = 0;
    for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
        password.append(getRandomPasswordCharacters(j));
        j++;
        if (j == 3) {
            j = 0;
        }
    }
    return password.toString();
}

private static String getRandomPasswordCharacters(int pos) {
    Random randomNum = new Random();
    StringBuilder randomChar = new StringBuilder();
    switch (pos) {
        case 0:
            randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
            break;
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
            break;
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
            break;
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
            break;
    }
    return randomChar.toString();

}

Вот однострочный код от AbacusUtil

String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())

Случайность не означает, что она должна быть уникальной. чтобы получить уникальные строки, используя:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'

используя библиотеку apache, это можно сделать одной строкой

import org.apache.commons.lang.RandomStringUtils;
RandomStringUtils.randomAlphanumeric(64);

вот документ http: // commons .apache.org / языки / API-2,3 / орг / Apache / обыкновенные / языки / RandomStringUtils.html

public static String randomSeriesForThreeCharacter() {
    Random r = new Random();
    String value="";
    char random_Char ;
    for(int i=0; i<10;i++)
    { 
        random_Char = (char) (48 + r.nextInt(74));
        value=value+random_char;
    }
    return value;
}

Я думаю, что это самое маленькое решение здесь, или почти одно из самых маленьких:

 public String generateRandomString(int length) {
    String randomString = "";

    final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890".toCharArray();
    final SecureRandom random = new SecureRandom();
    for (int i = 0; i < length; i++) {
        randomString = randomString + chars[random.nextInt(chars.length)];
    }

    return randomString;
}

Код работает просто отлично. Если вы используете этот метод, я рекомендую использовать более 10 символов. Столкновение происходит при 5 символах / 30362 итерации. Это заняло 9 секунд.

public static String getRandomString(int length) 
{
   String randomStr = UUID.randomUUID().toString();
   while(randomStr.length() < length) {
       randomStr += UUID.randomUUID().toString();
   }
   return randomStr.substring(0, length);
}

Может быть, это полезно

package password.generater;

import java.util.Random;

/**
 *
 * @author dell
 */
public class PasswordGenerater {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int length= 11;
        System.out.println(generatePswd(length));

        // TODO code application logic here
    }
    static char[] generatePswd(int len){
        System.out.println("Your Password ");
        String charsCaps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        String Chars="abcdefghijklmnopqrstuvwxyz";
        String nums="0123456789";
        String symbols="!@#$%^&*()_+-=.,/';:?><~*/-+";
        String passSymbols=charsCaps + Chars + nums +symbols;
        Random rnd=new Random();
        char[] password=new char[len];

        for(int i=0; i<len;i++){
            password[i]=passSymbols.charAt(rnd.nextInt(passSymbols.length()));
        }
      return password;

    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top