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

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

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

Ответ 1

Алгоритм

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

Реализация

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

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 2/(2q x), где n - количество фактически сгенерированных идентификаторов, q - количество различных символов в алфавите, а x - длина идентификаторов. Это должно быть очень маленькое число, например, 2-50 или меньше.

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

Сравнение с UUID

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

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

Если вы счастливы использовать классы Apache, вы можете использовать org.apache.commons.text.RandomStringGenerator (commons-text).

Пример:

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 устарел.

Ответ 6

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

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

Ответ 7

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

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

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

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

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

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

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

comparison of token sizes

For simple requirements 8 or 12 byte length might suffice, but with 16 bytes you are on the "safe side".

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

3. Бинарное в текстовое кодирование

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

  • Base64 каждый символ кодирует 6 бит, создавая 33% накладных расходов. К счастью, есть стандартные реализации в Java 8+ и Android. В более старой Java вы можете использовать любую из многочисленных сторонних библиотек. Если вы хотите, чтобы ваши токены были безопасными для URL, используйте url-safe версию 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-обсуждение о преобразовании в гекс здесь.

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

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

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

Не

  • ... используйте кодировку домашнего приготовления: лучше поддерживать и читать для других, если они увидят, какую стандартную кодировку вы используете вместо странных для циклов, создающих символы одновременно.
  • ... использовать 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 Tool

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

Ответ 8

с помощью Dollar должно быть простым:

// "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

Ответ 9

Здесь он находится в 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

Ответ 10

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

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 бита случайных значений. Поэтому, если вы хотите, вы можете усекать с конца, чтобы уменьшить размер UUID. Он не рекомендуется, но у вас все еще есть множество случайностей, достаточно для ваших записей 500k.

Ответ 11

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

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

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

Ответ 12

Альтернативой в 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();
}

Ответ 13

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

Ответ 14

Использование 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 to (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. Последняя проблема, если нам нужна строка с определенной длиной, random может генерировать небольшое число, поэтому длина не выполняется, поэтому нам нужно наложить строку на требуемую длину, предваряющую нули.

Ответ 15

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 = "[email protected]#$%^&*";
    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);
    }
}

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

Ответ 16

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

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

Ответ 17

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

Ответ 18

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

Ответ 19

  • Измените строковые символы в соответствии с вашими требованиями.

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


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

Ответ 20

Не очень нравится любой из этих ответов относительно "простого" решения: 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("-", "")

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

Ответ 21

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

Ответ 22

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

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

}

Ответ 23

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

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

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

Ответ 24

Вот однострочный код от 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 '-'

Ответ 25

Здесь это решение Scala:

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

Ответ 27

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

Ответ 28

public static String getRandomString(int length) {
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST".toCharArray();

        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        String randomStr = sb.toString();

        return randomStr;
    }

Ответ 29

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

 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 секунд.

Ответ 30

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