Jak wygenerować losowy ciąg alfanumeryczny?

Szukałem prostego algorytmu Java do generowania pseudolosowego ciągu alfanumerycznego. W mojej sytuacji byłby on używany jako unikalny identyfikator sesji/klucza, który "prawdopodobnie" byłby unikalny ponad 500K + generacji (moje potrzeby tak naprawdę nie wymagają niczego znacznie bardziej wyrafinowanego). Idealnie, byłbym w stanie określić długość w zależności od moich potrzeb wyjątkowości. Na przykład, wygenerowany ciąg o długości 12 może wyglądać jak "AEYGF7K0DM1X".

Author: Todd, 2008-09-03

30 answers

Algorytm

Aby wygenerować losowy ciąg znaków, połącz znaki losowane losowo z zestawu akceptowalnych symboli, aż ciąg osiągnie żądaną długość.

Implementacja

Oto dość prosty i bardzo elastyczny kod do generowania losowych identyfikatorów. przeczytaj następujące informacje , aby uzyskać ważne uwagi dotyczące aplikacji.

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

}

Przykłady użycia

Tworzenie niepewnego generatora dla 8-znakowego "identyfikator": {]}

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

Utwórz Bezpieczny generator identyfikatorów sesji:

RandomString session = new RandomString();

Utwórz generator z łatwymi do odczytania kodami do drukowania. Ciągi są dłuższe niż pełne ciągi alfanumeryczne, aby zrekompensować użycie mniejszej liczby symboli:

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

Użyj jako identyfikatory sesji

Generowanie identyfikatorów sesji, które mogą być unikalne, nie jest wystarczająco dobre, lub można po prostu użyć prostego licznika. Atakujący przejmują sesje, gdy przewidywalne identyfikatory są używany.

Istnieje napięcie między długością a bezpieczeństwem. Krótsze identyfikatory są łatwiejsze do odgadnięcia, ponieważ możliwości jest mniej. Jednak dłuższe identyfikatory zużywają więcej pamięci masowej i przepustowości. Większy zestaw symboli pomaga, ale może powodować problemy z kodowaniem, jeśli identyfikatory są dołączane do adresów URL lub ponownie wprowadzane ręcznie. Źródło losowości lub entropii dla identyfikatorów sesji powinno pochodzić z generatora liczb losowych zaprojektowanego do kryptografii. Jednakże, inicjalizacja tych generatorów może być czasami kosztowna obliczeniowo lub powolna, więc należy podjąć wysiłek, aby ponownie je wykorzystać, gdy jest to możliwe.

Użyj jako identyfikatory obiektów

Nie każda aplikacja wymaga bezpieczeństwa. Przypisanie losowe może być skutecznym sposobem generowania identyfikatorów przez wiele jednostek we współdzielonej przestrzeni bez jakiejkolwiek koordynacji lub partycjonowania. Koordynacja może być powolna, szczególnie w środowisku klastrowym lub rozproszonym, a rozdzielenie przestrzeni powoduje problemy gdy podmioty kończą z udziałami, które są zbyt małe lub zbyt duże.

Identyfikatory generowane bez podejmowania środków w celu uczynienia ich nieprzewidywalnymi powinny być chronione w inny sposób, Jeśli atakujący może je przeglądać i manipulować, jak to ma miejsce w większości aplikacji internetowych. Powinien istnieć oddzielny system autoryzacji, który chroni obiekty, których identyfikator może odgadnąć atakujący bez uprawnień dostępu.

Należy również zwrócić uwagę na używanie identyfikatorów, które są długie wystarczająco, aby kolizje były mało prawdopodobne, biorąc pod uwagę przewidywaną całkowitą liczbę identyfikatorów. Jest to określane jako " paradoks urodzinowy."prawdopodobieństwo kolizji, p , wynosi w przybliżeniu n2/(2q x), gdzie n jest liczbą faktycznie wygenerowanych identyfikatorów, q jest liczbą odrębnych symboli w alfabecie, a x jest długością identyfikatorów. Powinna to być bardzo mała liczba, jak 2-50 lub mniej.

Wypracowanie tego pokazuje, że szansa kolizji pomiędzy 500K 15-znakowymi identyfikatorami wynosi ok. 2-52, co jest prawdopodobnie mniej prawdopodobne niż niewykryte błędy z promieniowania kosmicznego, itp.

Porównanie z uuid

Zgodnie z ich specyfikacją uuid nie są zaprojektowane tak, aby były nieprzewidywalne i nie powinny być używane jako identyfikatory sesji.

Uuidy w standardowym formacie zajmują dużo miejsca: 36 znaków dla zaledwie 122 bitów entropii. (Nie wszystkie bity "losowego" identyfikatora UUID są wybierane losowo.) Losowo wybrany ciąg alfanumeryczny zawiera więcej entropii w zaledwie 21 znakach.

Uuid nie są elastyczne; mają ustandaryzowaną strukturę i układ. To jest ich główna cnota, jak również ich główna słabość. Przy współpracy ze stroną zewnętrzną pomocna może być standaryzacja oferowana przez uuid. Do użytku wyłącznie wewnętrznego mogą być nieefektywne.

 1416
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 23:34:53

Java dostarcza sposobu, aby to zrobić bezpośrednio. Jeśli nie chcesz kresek, łatwo je rozebrać. Wystarczy użyć 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;
    }
}

Wyjście:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316
 746
Author: Steve McLeod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 06:09:52
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();
}
 474
Author: maxp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 10:41:59

Jeśli chcesz używać klas Apache, możesz użyć org.apache.commons.text.RandomStringGenerator (commons-text).

Przykład:

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

Od commons-lang 3.6, {[2] } jest przestarzały.

 457
Author: numéro6,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 07:58:04

W jednym wierszu:

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

Http://mynotes.wordpress.com/2009/07/23/java-generating-random-string/

 94
Author: 3 revs, 3 users 71%anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 02:29:50

Możesz użyć biblioteki Apache do tego: Randomstringuls

RandomStringUtils.randomAlphanumeric(20).toUpperCase();
 89
Author: manish_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-09 14:15:43

Użycie powinno być proste jak:

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

Wychodzi coś takiego:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7
 38
Author: dfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 02:30:13

Jest to łatwe do osiągnięcia bez żadnych zewnętrznych bibliotek.

1. Kryptograficzne Generowanie Pseudo Losowych Danych

Najpierw potrzebujesz kryptograficznego PRNG. Java ma SecureRandom do tego zazwyczaj używa się najlepszego źródła entropii na maszynie (np. /dev/random). Czytaj więcej tutaj.

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

Uwaga: SecureRandom jest najwolniejszym, ale najbezpieczniejszym sposobem generowania losowych bajtów w Javie. Polecam jednak nie brać pod uwagę wydajności tutaj, ponieważ zwykle nie ma to realnego wpływu na Twoją aplikację, chyba że musisz wygenerować miliony tokenów na sekundę.

2. Wymagana przestrzeń możliwych wartości

Następnie musisz zdecydować, "jak wyjątkowy" musi być twój żeton. Cały i jedyny punkt rozważania entropii jest upewnienie się, że system jest w stanie oprzeć się atakom brute force: przestrzeń możliwych wartości musi być tak duża, że każdy atakujący może spróbować tylko znikomej części wartości w nie-Śmieszne czas1. Unikalne identyfikatory, takie jak losowe UUID mieć 122bit entropii (tj. 2^122 = 5.3x10^36) - szansa kolizji to" *(...) aby istnieje jedna na miliard szans na powielenie, należy wygenerować 103 biliony uuid wersji 42". wybieramy 128 bitów, ponieważ pasuje dokładnie do 16 bajtów i jest postrzegany jako wysoce wystarczający, aby być unikalny dla praktycznie każdego, ale najbardziej ekstremalnych przypadków użycia i nie muszę myśleć o duplikatach. Oto prosta tabela porównawcza entropii zawierająca prostą analizę problemu urodzinowego .

Porównanie rozmiarów tokenów

dla prostych wymagań może wystarczyć 8 lub 12 bajtów, ale z 16 bajtami jesteś po "bezpiecznej stronie".

I to w zasadzie wszystko. Ostatnią rzeczą jest myślenie o kodowaniu, aby można było przedstawić go jako tekst drukowany(read, a String).

3. Binary to Text Kodowanie

Typowe kodowania to:

  • Base64 każdy znak koduje 6bit tworząc 33% narzutu. Niestety nie ma standardowej implementacji w JDK (7 i poniżej - jest w Android i Java 8+). Aleistnieją liczne biblioteki , które dodają to. Minusem jest to, że standard Base64 nie jest bezpieczny dla np. adresy URL i jako nazwa pliku w większości systemów plików wymagających dodatkowego kodowania (np. url kodowanie ) lub URL bezpieczna wersja Base64 jest używany . Przykładowe kodowanie 16 bajtów z wypełnieniem: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 każdy znak koduje 5bit tworząc 40% narzutu. Użyje A-Z i 2-7, dzięki czemu będzie wystarczająco efektywny przestrzennie, a jednocześnie będzie niewrażliwy na wielkość liter. Nie ma standardowej implementacji w JDK. Przykładowe kodowanie 16 bajtów bez wypełnienia: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (hex) co znak koduje 4bit wymagając 2 znaków na bajt (tj. 16 bajtów tworzy ciąg o długości 32). Dlatego hex jest mniej przestrzenny niż Base32, ale jest bezpieczny w użyciu w większości przypadków (url), ponieważ używa tylko 0-9 i A do F. Przykład kodowania 16 bajtów: 4fa3dd0f57cb3bf331441ed285b27735. Zobacz dyskusję SO na temat konwersji na hex tutaj.

Dodatkowe kodowania, takie jak Base85 i egzotyczne Base122 istnieją z lepszą/gorszą wydajnością przestrzeni. Możesz stworzyć własne kodowanie (co w zasadzie większość odpowiedzi w tym wątku robi), ale odradzam, jeśli nie masz bardzo konkretnych wymagań. Zobacz więcej schematów kodowania w artykule Wikipedii.

4. Podsumowanie i przykład

  • użycie SecureRandom
  • Użyj co najmniej 16 bajtów (2^128) możliwych wartości
  • Koduj zgodnie z Twoimi wymaganiami (Zwykle hex lub base32 jeśli potrzebujesz, aby alfanumeryczny)

Nie

  • ... użyj kodowania home brew: lepiej utrzymywalne i czytelne dla innych, jeśli zobaczą, jakiego standardowego kodowania używasz, zamiast dziwne dla pętli tworzących znaki na raz.
  • ... uuid: marnujesz 6 bitów entropii i masz verbose string representation
Przykład: Hex Token Generator
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

Przykład: Narzędzie

Jeśli chcesz gotowy do użycia narzędzie cli możesz użyć Kości: https://github.com/patrickfav/dice

 34
Author: for3st,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-22 14:39:29

Zaskakujące, że nikt tu tego nie zasugerował, ale:

import java.util.UUID

UUID.randomUUID().toString();
Spokojnie.

Zaletą tego jest to, że UUIDs są ładne i długie i gwarantowane, że będą prawie niemożliwe do zderzenia.

Wikipedia ma dobre wyjaśnienie:

" ...dopiero po wygenerowaniu 1 miliarda uuid co sekundę przez następne 100 lat prawdopodobieństwo utworzenia tylko jednego duplikatu wyniosłoby około 50%."

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

Pierwsze 4 bity to typ wersji i 2 dla wariantu, więc otrzymujesz 122 bity losowe. Więc jeśli chcesz , możesz obciąć od końca, aby zmniejszyć rozmiar UUID. Nie jest to zalecane, ale nadal masz mnóstwo losowości, wystarczy na twoje rekordy 500K łatwe.

 29
Author: Michael Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-16 11:49:00

Tutaj jest w Javie:

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

Oto przykładowy przebieg:

scala> RandomAlphaNum.gen(42)
res3: java.lang.String = uja6snx21bswf9t89s00bxssu8g6qlu16ffzqaxxoy
 28
Author: Apocalisp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-03 17:16:38

Krótkie i łatwe rozwiązanie, ale używa tylko małych liter i cyfr:

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

Rozmiar jest około 12 cyfr do bazy 36 i nie można go poprawić dalej, w ten sposób. Oczywiście można dołączyć wiele instancji.

 22
Author: user unknown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 23:29:20

Alternatywą w Javie 8 jest:

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();
}
 12
Author: Howard Lovatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 19:09:43
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;
}
 8
Author: rina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-09 04:47:13

Używanie uuid jest niebezpieczne, ponieważ części UUID nie są przypadkowe. Procedura @ erickson jest bardzo zgrabna, ale nie tworzy ciągów o tej samej długości. Poniższy fragment powinien być wystarczający:

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

Dlaczego wybrać length*5. Załóżmy prosty przypadek losowego ciągu o długości 1, więc jeden losowy znak. Aby otrzymać losowy znak zawierający wszystkie cyfry 0-9 i znaki a-z, potrzebujemy losowej liczby z zakresu od 0 do 35, aby uzyskać jeden z każdego znaku. BigInteger dostarcza konstruktor do generowania liczby losowej, równomiernie rozłożonej w zakresie 0 to (2^numBits - 1). Niestety 35 nie jest liczbą, którą można otrzymać przez 2 ^ numBits - 1. Mamy więc dwie opcje: albo iść z 2^5-1=31 albo 2^6-1=63. Jeśli wybierzemy 2^6 otrzymamy wiele liczb "unnecesarry" / "longer". Dlatego 2^5 jest lepszą opcją, nawet jeśli tracimy 4 znaki (w-z). Aby wygenerować ciąg o określonej długości, możemy po prostu użyć liczby 2^(length*numBits)-1. Ostatni problem, jeśli chcemy ciąg przy pewnej długości losowa może wygenerować małą liczbę, więc długość nie jest spełniona, więc musimy ustawić ciąg na wymaganą długość poprzedzającą zera.

 8
Author: Kristian Kraljic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-11 10:56:42
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);
    }
}

Więc to co robi to po prostu dodać hasło do łańcucha i ... yeah works good check it out... bardzo proste. I wrote it

 7
Author: cmpbah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-17 09:42:20

Znalazłem rozwiązanie, które generuje losowy łańcuch zakodowany szesnastkowo. Dostarczony test jednostkowy zdaje się pasować do mojego podstawowego przypadku użycia. Chociaż jest to nieco bardziej złożone niż niektóre z innych udzielonych odpowiedzi.

/**
 * 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);
        }
    }
}
 5
Author: Todd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 06:49:20
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;
    }
}
 5
Author: Jameskittu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 06:50:34
  1. Zmień znaki ciągu zgodnie z wymaganiami.

  2. Ciąg jest niezmienny. Tutaj StringBuilder.append jest bardziej wydajne niż łączenie łańcuchów.


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();
    }
 5
Author: frisky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-31 17:14:09
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);
        }
    }
}
 4
Author: Suganya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 06:51:18

Nie podoba mi się żadna z tych odpowiedzi dotyczących "prostego" rozwiązania: S

Wybrałbym prosty;), czysty Java, jeden liner (Entropia opiera się na losowej długości łańcucha i podanym zestawie znaków):

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

Lub (nieco bardziej czytelny stary sposób)

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

Ale z drugiej strony można również wybrać UUID, który ma całkiem dobrą entropię ( https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions):

UUID.randomUUID().toString().replace("-", "")
Mam nadzieję, że to pomoże.
 4
Author: Patrik Bego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 15:55:12

Oto rozwiązanie Scali:

(for (i <- 0 until rnd.nextInt(64)) yield { 
  ('0' + rnd.nextInt(64)).asInstanceOf[Char] 
}) mkString("")
 3
Author: Ugo Matrangolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-24 11:11:01

Możesz użyć klasy uuid z Komunikatem getLeastSignificantBits (), aby uzyskać 64bit losowych danych, a następnie przekonwertować je na liczbę radix 36 (tzn. łańcuch składający się z 0-9, A-Z):

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

Daje to ciąg o długości do 13 znaków. Używamy matematyki.abs (), aby upewnić się, że nie ma znaku minus.

 3
Author: neuhaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-29 14:07:23

Możesz użyć następującego kodu, jeśli hasło obowiązkowe zawiera cyfry alfabetycznych znaków specjalnych:

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

}
 3
Author: Prasobh.K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 06:52:26

Oto jednolinijkowy kod AbacusUtil

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

Random nie oznacza, że musi być unikalny. aby uzyskać unikalne ciągi, użyj:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'
 3
Author: Developer of AbacusUtil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 21:45:59

Mówisz "proste", ale na wypadek, gdyby ktoś jeszcze szukał czegoś, co spełnia bardziej rygorystyczne wymagania bezpieczeństwa, możesz rzucić okiem na jpwgen . jpwgen jest wzorowany na pwgen w Uniksie i jest bardzo konfigurowalny.

 3
Author: michaelok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-26 22:47:13
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;
}
 3
Author: duggu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 23:30:48

Używając biblioteki apache można to zrobić w jednej linii

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

Oto doc http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/RandomStringUtils.html

 2
Author: hridayesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-15 07:52:12

Maybe this is helpful

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;

    }
}
 2
Author: 2 revs, 2 users 97%user5138430,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-28 09:49:48

Najlepsza Metoda Generatora Losowych Ciągów

public class RandomStringGenerator{

    private static int randomStringLength = 25 ;
    private static boolean allowSpecialCharacters = true ;
    private static String specialCharacters = "!@$%*-_+:";
    private static boolean allowDuplicates = false ;

    private static boolean isAlphanum = false;
    private static boolean isNumeric = false;
    private static boolean isAlpha = false;
    private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
    private static boolean mixCase = false;
    private static final String capAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String num = "0123456789";

    public static String getRandomString() {
        String returnVal = "";
        int specialCharactersCount = 0;
        int maxspecialCharacters = randomStringLength/4;

        try {
            StringBuffer values = buildList();
            for (int inx = 0; inx < randomStringLength; inx++) {
                int selChar = (int) (Math.random() * (values.length() - 1));
                if (allowSpecialCharacters)
                {
                    if (specialCharacters.indexOf("" + values.charAt(selChar)) > -1)
                    {
                        specialCharactersCount ++;
                        if (specialCharactersCount > maxspecialCharacters)
                        {
                            while (specialCharacters.indexOf("" + values.charAt(selChar)) != -1)
                            {
                                selChar = (int) (Math.random() * (values.length() - 1));
                            }
                        }
                    }
                }
                returnVal += values.charAt(selChar);
                if (!allowDuplicates) {
                    values.deleteCharAt(selChar);
                }
            }
        } catch (Exception e) {
            returnVal = "Error While Processing Values";
        }
        return returnVal;
    }

    private static StringBuffer buildList() {
        StringBuffer list = new StringBuffer(0);
        if (isNumeric || isAlphanum) {
            list.append(num);
        }
        if (isAlpha || isAlphanum) {
            list.append(alphabet);
            if (mixCase) {
                list.append(capAlpha);
            }
        }
        if (allowSpecialCharacters)
        {
            list.append(specialCharacters);
        }
        int currLen = list.length();
        String returnVal = "";
        for (int inx = 0; inx < currLen; inx++) {
            int selChar = (int) (Math.random() * (list.length() - 1));
            returnVal += list.charAt(selChar);
            list.deleteCharAt(selChar);
        }
        list = new StringBuffer(returnVal);
        return list;
    }   

}
 1
Author: Bhavik Ambani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-28 07:33:52
public static String getRandomString(int length) 
{
   String randomStr = UUID.randomUUID().toString();
   while(randomStr.length() < length) {
       randomStr += UUID.randomUUID().toString();
   }
   return randomStr.substring(0, length);
}
 1
Author: Vin Ferothas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-03 06:59:05