Domanda

Ho cercato un semplice Algoritmo Java per generare una stringa alfanumerica pseudo-casuale.Nella mia situazione verrebbe utilizzato come identificatore di sessione/chiave univoco che "probabilmente" sarebbe univoco 500K+ generazione (le mie esigenze in realtà non richiedono nulla di molto più sofisticato).

Idealmente, sarei in grado di specificare una lunghezza in base alle mie esigenze di unicità.Ad esempio, una stringa generata di lunghezza 12 potrebbe assomigliare a qualcosa del genere "AEYGF7K0DM1X".

È stato utile?

Soluzione

Algoritmo

Per generare una stringa casuale, concatenare i caratteri estratti casualmente dall'insieme di simboli accettabili finché la stringa non raggiunge la lunghezza desiderata.

Implementazione

Ecco un codice abbastanza semplice e molto flessibile per generare identificatori casuali. Leggi le informazioni che seguono per importanti note applicative.

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

}

Esempi di utilizzo

Crea un generatore non sicuro per identificatori di 8 caratteri:

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

Crea un generatore sicuro per gli identificatori di sessione:

RandomString session = new RandomString();

Crea un generatore con codici di facile lettura per la stampa.Le stringhe sono più lunghe delle stringhe alfanumeriche complete per compensare l'utilizzo di un minor numero di simboli:

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

Utilizzare come identificatori di sessione

Generare identificatori di sessione che probabilmente saranno univoci non è sufficiente, oppure potresti semplicemente utilizzare un semplice contatore.Gli aggressori dirottano le sessioni quando vengono utilizzati identificatori prevedibili.

C’è tensione tra durata e sicurezza.Gli identificatori più brevi sono più facili da indovinare perché ci sono meno possibilità.Ma gli identificatori più lunghi consumano più spazio di archiviazione e larghezza di banda.Un insieme più ampio di simboli aiuta, ma potrebbe causare problemi di codifica se gli identificatori vengono inclusi negli URL o reinseriti manualmente.

La fonte sottostante di casualità, o entropia, per gli identificatori di sessione dovrebbe provenire da un generatore di numeri casuali progettato per la crittografia.Tuttavia, l'inizializzazione di questi generatori a volte può essere computazionalmente costosa o lenta, quindi è necessario fare uno sforzo per riutilizzarli quando possibile.

Utilizzare come identificatori di oggetti

Non tutte le applicazioni richiedono sicurezza.L'assegnazione casuale può essere un modo efficace per consentire a più entità di generare identificatori in uno spazio condiviso senza alcun coordinamento o partizionamento.Il coordinamento può essere lento, soprattutto in un ambiente cluster o distribuito, e la suddivisione di uno spazio causa problemi quando le entità si ritrovano con condivisioni troppo piccole o troppo grandi.

Gli identificatori generati senza adottare misure per renderli imprevedibili dovrebbero essere protetti con altri mezzi se un utente malintenzionato potrebbe essere in grado di visualizzarli e manipolarli, come accade nella maggior parte delle applicazioni web.Dovrebbe esserci un sistema di autorizzazione separato che protegga gli oggetti il ​​cui identificatore può essere indovinato da un utente malintenzionato senza autorizzazione di accesso.

È inoltre necessario prestare attenzione a utilizzare identificatori sufficientemente lunghi da rendere improbabili le collisioni dato il numero totale previsto di identificatori.Questo viene definito "il paradosso del compleanno". La probabilità di una collisione, P, è di circa n2/(2qX), Dove N è il numero di identificatori effettivamente generati, Q è il numero di simboli distinti nell'alfabeto, e X è la lunghezza degli identificatori.Dovrebbe essere un numero molto piccolo, come 2‑50 o meno.

L'elaborazione di questo mostra che la possibilità di collisione tra 500.000 identificatori di 15 caratteri è di circa 2‑52, che è probabilmente meno probabile degli errori non rilevati derivanti dai raggi cosmici, ecc.

Confronto con gli UUID

Secondo le loro specifiche, gli UUID non sono progettati per essere imprevedibili e non dovrebbe essere utilizzati come identificatori di sessione.

Gli UUID nel loro formato standard occupano molto spazio:36 caratteri per soli 122 bit di entropia.(Non tutti i bit di un UUID "casuale" sono selezionati in modo casuale.) Una stringa alfanumerica scelta a caso racchiude più entropia in soli 21 caratteri.

Gli UUID non sono flessibili;hanno una struttura e un layout standardizzati.Questa è la loro principale virtù, ma anche la loro principale debolezza.Quando si collabora con una parte esterna, la standardizzazione offerta dagli UUID può essere utile.Per uso puramente interno, possono essere inefficienti.

Altri suggerimenti

Java fornisce un modo per farlo direttamente.Se non vuoi i trattini, sono facili da togliere.Basta usare 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;
    }
}

Produzione:

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

Se sei felice di usare le classi Apache, potresti usare org.apache.commons.text.RandomStringGenerator (testo comune).

Esempio:

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

A partire da commons-lang 3.6, RandomStringUtils è deprecato.

In una riga:

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

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

Puoi usare la libreria Apache per questo: RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

Questo è facilmente ottenibile senza librerie esterne.

1.Generazione di dati pseudocasuali crittografici

Per prima cosa hai bisogno di un PRNG crittografico.Java ha SecureRandom per questo in genere utilizza la migliore fonte di entropia sulla macchina (ad es. /dev/random) . Leggi di più qui.

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

Nota: SecureRandom è il modo più lento, ma più sicuro in Java per generare byte casuali.Raccomando tuttavia di NON considerare le prestazioni qui poiché di solito non hanno alcun impatto reale sulla tua applicazione a meno che tu non debba generare milioni di token al secondo.

2.Spazio richiesto dei valori possibili

Successivamente devi decidere "quanto unico" deve essere il tuo token.L’unico scopo di considerare l’entropia è assicurarsi che il sistema possa resistere agli attacchi di forza bruta:lo spazio dei valori possibili deve essere così ampio che qualsiasi utente malintenzionato possa provare solo una percentuale trascurabile dei valori in un tempo non ridicolo1.Identificatori univoci come casuali UUID hanno 122 bit di entropia (es.2^122 = 5,3x10^36) - la possibilità di collisione è "*(...) affinché ci sia una possibilità su un miliardo di duplicazione, è necessario generare 103 trilioni di UUID della versione 42". Sceglieremo 128 bit poiché sta esattamente in 16 byte ed è visto come altamente sufficiente per essere unici praticamente per tutti i casi d'uso, tranne quelli più estremi, e non devi pensare ai duplicati.Ecco una semplice tabella comparativa dell'entropia che include una semplice analisi dei problema del compleanno.

comparison of token sizes

Per esigenze semplici potrebbero bastare 8 o 12 byte di lunghezza, ma con 16 byte si è "al sicuro".

E questo è fondamentalmente tutto.L'ultima cosa è pensare alla codifica in modo che possa essere rappresentato come testo stampabile (leggi, a String).

3.Codifica da binario a testo

Le codifiche tipiche includono:

  • Base64 ogni carattere codifica a 6 bit creando un sovraccarico del 33%.Fortunatamente ci sono implementazioni standard in Java8+ E Androide.Con Java precedente puoi utilizzare uno qualsiasi dei file numerose biblioteche di terze parti.Se vuoi che i tuoi token siano sicuri per gli URL, usa il file sicuro per gli URL versione di RFC4648 (che di solito è supportata dalla maggior parte delle implementazioni).Esempio di codifica di 16 byte con riempimento: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 ogni carattere codifica 5 bit creando un sovraccarico del 40%.Questo utilizzerà A-Z E 2-7 rendendolo ragionevolmente efficiente in termini di spazio pur essendo alfanumerico senza distinzione tra maiuscole e minuscole.Non c'è implementazione standard nel JDK.Esempio di codifica di 16 byte senza riempimento: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (hex) ogni carattere codifica 4 bit richiedendo 2 caratteri per byte (es.16 byte creano una stringa di lunghezza 32).Pertanto hex è meno efficiente in termini di spazio rispetto a Base32 ma è sicuro da usare nella maggior parte dei casi (url) poiché utilizza solo 0-9 E A A F.Esempio di codifica 16 byte: 4fa3dd0f57cb3bf331441ed285b27735. Vedi una discussione SO sulla conversione in esadecimale qui.

Codifiche aggiuntive come Base85 e l'esotico Base122 esistere con una migliore/peggiore efficienza spaziale.Puoi creare la tua codifica (cosa che sostanzialmente fa la maggior parte delle risposte in questo thread) ma ti sconsigliamo di farlo, se non hai requisiti molto specifici.Vedere più schemi di codifica nell'articolo di Wikipedia.

4.Riepilogo ed esempio

  • Utilizzo SecureRandom
  • Utilizzare almeno 16 byte (2^128) di valori possibili
  • Codifica in base alle tue esigenze (di solito hex O base32 se ti serve che sia alfanumerico)

Non

  • ...usa la codifica della tua birra fatta in casa: meglio gestibile e leggibile per gli altri se vedono quale codifica standard usi invece di strani cicli for che creano caratteri alla volta.
  • ...usa l'UUID: non ha garanzie sulla casualità;stai sprecando 6 bit di entropia e hai una rappresentazione dettagliata delle stringhe

Esempio:Generatore di token esadecimali

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

Esempio:Generatore di token Base64 (URL sicuro)

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

Esempio:Strumento CLI Java

Se vuoi uno strumento cli pronto all'uso puoi usare dice: https://github.com/patrickfav/dice

utilizzando Dollaro dovrebbe essere semplice come:

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

restituisce qualcosa del genere:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

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

Ecco un esempio di esecuzione:

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

Sorprendentemente nessuno qui lo ha suggerito ma:

import java.util.UUID

UUID.randomUUID().toString();

Facile.

Il vantaggio di ciò è che gli UUID sono belli e lunghi e garantiscono che sia quasi impossibile entrare in collisione.

Wikipedia ne dà una buona spiegazione:

"...solo dopo aver generato 1 miliardo di UUID al secondo per i prossimi 100 anni, la probabilità di creare un solo duplicato sarebbe di circa il 50%."

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

I primi 4 bit sono il tipo di versione e 2 per la variante, quindi ottieni 122 bit casuali.Quindi se tu Volere a puoi troncare dalla fine per ridurre la dimensione dell'UUID.Non è raccomandato ma hai ancora un sacco di casualità, sufficiente per i tuoi record da 500k facili.

Una soluzione breve e semplice, ma utilizza solo lettere minuscole e numeri:

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

La dimensione è di circa 12 cifre in base 36 e non può essere ulteriormente migliorata in questo modo.Ovviamente puoi aggiungere più istanze.

Un'alternativa in 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;
}

L'uso degli UUID non è sicuro, perché parti dell'UUID non sono affatto casuali.La procedura di @erickson è molto curata, ma non crea stringhe della stessa lunghezza.Il seguente snippet dovrebbe essere sufficiente:

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

Perché scegliere length*5.Assumiamo il caso semplice di una stringa casuale di lunghezza 1, quindi un carattere casuale.Per ottenere un carattere casuale contenente tutte le cifre da 0 a 9 e i caratteri a-z, avremmo bisogno di un numero casuale compreso tra 0 e 35 per ottenere uno di ciascun carattere. BigInteger fornisce un costruttore per generare un numero casuale, distribuito uniformemente nell'intervallo 0 to (2^numBits - 1).Sfortunatamente 35 non è un numero che possa essere ricevuto da 2^numBits - 1.Quindi abbiamo due opzioni:O vai con 2^5-1=31 O 2^6-1=63.Se potessimo scegliere 2^6 otterremmo molti numeri "non necessari" / "più lunghi".Perciò 2^5 è l'opzione migliore, anche se perdiamo 4 caratteri (w-z).Per generare ora una stringa di una certa lunghezza possiamo semplicemente utilizzare a 2^(length*numBits)-1 numero.L'ultimo problema, se vogliamo una stringa con una certa lunghezza, random potrebbe generare un numero piccolo, quindi la lunghezza non viene soddisfatta, quindi dobbiamo riempire la stringa alla lunghezza richiesta anteponendo degli zeri.

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

Quindi ciò che fa è semplicemente aggiungere la password nella stringa e...sì, funziona bene, dai un'occhiata...molto semplice.l'ho scritto io

Ho trovato questa soluzione che genera una stringa con codifica esadecimale casuale.Il test unitario fornito sembra resistere al mio caso d'uso principale.Tuttavia, è leggermente più complesso di alcune delle altre risposte fornite.

/**
 * 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. Cambia i caratteri della stringa secondo le tue esigenze.

  2. La stringa è immutabile.Qui StringBuilder.append è più efficiente della concatenazione di stringhe.


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

Non mi piace molto nessuna di queste risposte riguardanti la soluzione "semplice": S

Vorrei optare per un semplice;), puro Java, una riga (l'entropia si basa sulla lunghezza casuale della stringa e sul set di caratteri specificato):

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

o (un po' più leggibile alla vecchia maniera)

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

Ma d'altra parte potresti anche utilizzare l'UUID che ha un'entropia piuttosto buona (https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions):

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

Spero che aiuti.

Hai menzionato "semplice", ma nel caso in cui qualcun altro stia cercando qualcosa che soddisfi requisiti di sicurezza più rigorosi, potresti dare un'occhiata a jpwgen.jpwgen è modellato su pwgen in Unix ed è molto configurabile.

Ecco una soluzione Scala:

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

Puoi utilizzare la classe UUID con il suo messaggio getLeastSignificantBits() per ottenere 64 bit di dati casuali, quindi convertirli in un numero radice 36 (ad es.una stringa composta da 0-9,A-Z):

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

Ciò produce una stringa lunga fino a 13 caratteri.Usiamo Math.abs() per assicurarci che non si infiltri un segno meno.

Puoi utilizzare il seguente codice, se la tua password contiene obbligatoriamente numeri, caratteri alfabetici speciali:

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

}

Ecco il codice di una riga di AbacusUtil

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

Casuale non significa che debba essere unico.per ottenere stringhe univoche, utilizzando:

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

utilizzando la libreria Apache è possibile farlo in una riga

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

ecco il dottore http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/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;
}

Penso che questa sia la soluzione più piccola qui, o quasi una delle più piccole:

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

Il codice funziona perfettamente.Se utilizzi questo metodo, ti consiglio di utilizzare più di 10 caratteri.La collisione avviene a 5 caratteri/30362 iterazioni.Ci sono voluti 9 secondi.

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

Forse questo è utile

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;

    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top