Een willekeurige alfanumerieke tekenreeks genereren

Ik ben op zoek naar een eenvoudigJava-algoritme om een pseudo-willekeurige alfanumerieke reeks te genereren. In mijn situatie zou het worden gebruikt als een unieke sessie-/sleutelidentificatie die “waarschijnlijk” uniek zou zijn over de 500K+generatie (mijn behoeften vereisen niet echt iets veel geavanceerder).

Idealiter zou ik een lengte kunnen specificeren, afhankelijk van mijn unieke behoeften. Een gegenereerde tekenreeks met lengte 12 kan er bijvoorbeeld ongeveer zo uitzien als "AEYGF7K0DM1X".


Antwoord 1, autoriteit 100%

Algoritme

Om een willekeurige tekenreeks te genereren, voegt u willekeurig getrokken tekens samen uit de reeks aanvaardbare symbolen totdat de tekenreeks de gewenste lengte heeft bereikt.

Implementatie

Hier is een vrij eenvoudige en zeer flexibele code voor het genereren van willekeurige identifiers. Lees de informatie die volgtvoor belangrijke applicatie-opmerkingen.

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

Gebruiksvoorbeelden

Maak een onveilige generator voor identificatoren van 8 tekens:

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

Maak een beveiligde generator voor sessie-ID’s:

RandomString session = new RandomString();

Maak een generator met eenvoudig te lezen codes voor afdrukken. De snaren zijn langer dan volledige alfanumerieke snaren om te compenseren voor het gebruik van minder symbolen:

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

Gebruik als session-ID’s

Genererende sessie-ID’s die waarschijnlijk uniek zijn, is niet goed genoeg, of u kunt gewoon een eenvoudige teller gebruiken. Aanvallers kaping sessies wanneer voorspelbare identificatoren worden gebruikt.

Er is spanning tussen lengte en zekerheid. Kortere identifiers zijn gemakkelijker te raden, omdat er minder mogelijkheden zijn. Maar langere ID’s verbruiken meer opslagruimte en bandbreedte. Een grotere set symbolen helpt, maar kan coderingsproblemen veroorzaken als identifiers worden opgenomen in URL’s of handmatig opnieuw worden ingevoerd.

De onderliggende bron van willekeur, of entropie, voor sessie-ID’s moet afkomstig zijn van een generator voor willekeurige getallen die is ontworpen voor cryptografie. Het initialiseren van deze generatoren kan soms echter rekenkundig duur of traag zijn, dus er moet moeite worden gedaan om ze waar mogelijk opnieuw te gebruiken.

Gebruiken als object-ID’s

Niet elke applicatie vereist beveiliging. Willekeurige toewijzing kan een efficiënte manier zijn voor meerdere entiteiten om identifiers te genereren in een gedeelde ruimte zonder enige coördinatie of partitionering. Coördinatie kan traag zijn, vooral in een geclusterde of gedistribueerde omgeving, en het opsplitsen van een ruimte veroorzaakt problemen wanneer entiteiten eindigen met aandelen die te klein of te groot zijn.

Identifiers die zijn gegenereerd zonder maatregelen te nemen om ze onvoorspelbaar te maken, moeten op een andere manier worden beschermd als een aanvaller ze zou kunnen bekijken en manipuleren, zoals in de meeste webapplicaties gebeurt. Er zou een apart autorisatiesysteem moeten zijn dat objecten beschermt waarvan de identifier door een aanvaller kan worden geraden zonder toegangsrechten.

Er moet ook op worden gelet dat identifiers worden gebruikt die lang genoeg zijn om botsingen onwaarschijnlijk te maken, gezien het verwachte totale aantal identifiers. Dit wordt de ‘verjaardagsparadox’ genoemd. De kans op een botsing,p, is ongeveer n< sup>2/(2qx), waarbij nhet aantal werkelijk gegenereerde ID’s is, qhet aantal verschillende symbolen in het alfabet, en xis de lengte van de identifiers. Dit moet een heel klein aantal zijn, zoals 2-50of minder.

Als we dit uitwerken, blijkt dat de kans op een botsing tussen 500k identificatiecodes van 15 tekens ongeveer 2‑52is, wat waarschijnlijk minder waarschijnlijk is dan onopgemerkte fouten van kosmische straling, enz.

Vergelijking met UUID’s

Volgens hun specificatie zijn UUID’sniet ontworpen om onvoorspelbaar te zijn, en mag nietworden gebruikt als sessie-ID’s.

UUID’s in hun standaardformaat nemen veel ruimte in beslag: 36 tekens voor slechts 122 bits entropie. (Niet alle bits van een “willekeurige” UUID worden willekeurig geselecteerd.) Een willekeurig gekozen alfanumerieke tekenreeks bevat meer entropie in slechts 21 tekens.

UUID’s zijn niet flexibel; ze hebben een gestandaardiseerde structuur en lay-out. Dit is zowel hun voornaamste deugd als hun voornaamste zwakte. Bij samenwerking met een externe partij kan de standaardisatie van UUID’s behulpzaam zijn. Voor puur intern gebruik kunnen ze inefficiënt zijn.


Antwoord 2, autoriteit 54%

Java biedt een manier om dit direct te doen. Als u de streepjes niet wilt, kunt u ze eenvoudig verwijderen. Gebruik gewoon 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;
    }
}

Uitvoer

uuid = 2d7428a6-b58c-4008-8575-f05549f16316

Antwoord 3, autoriteit 38%

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

Antwoord 4, autoriteit 31%

Als je Apache-klassen wilt gebruiken, kun je org.apache.commons.text.RandomStringGenerator(Apache Commons-tekst).

Voorbeeld:

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

Sinds Apache Commons Lang3.6, is RandomStringUtilsverouderd.


Antwoord 5, autoriteit 8%

Je kunt hiervoor een Apache Commons-bibliotheek gebruiken, RandomStringUtils:

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

Antwoord 6, autoriteit 7%

In één regel:

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

Bron: Java – genereert een willekeurige tekenreeks


Antwoord 7, autoriteit 5%

Dit is gemakkelijk te bereiken zonder externe bibliotheken.

1. Cryptografische pseudo-willekeurige gegevensgeneratie (PRNG)

Eerst heb je een cryptografische PRNG nodig. Java heeft SecureRandomdaarvoor en gebruikt doorgaans de beste entropiebron op de machine (bijv. /dev/random). Lees hier meer.

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

Opmerking:SecureRandomis de langzaamste, maar veiligste manier in Java om willekeurige bytes te genereren. Ik raad echter aan nietde prestaties hier te overwegen, omdat het meestal geen echte impact heeft op uw toepassing, tenzij u miljoenen tokens per seconde moet genereren.

2. Vereiste ruimte met mogelijke waarden

Vervolgens moet je beslissen “hoe uniek” je token moet zijn. Het hele en enige punt van het overwegen van entropie is ervoor te zorgen dat het systeem brute force-aanvallen kan weerstaan: de ruimte van mogelijke waarden moet zo groot zijn dat een aanvaller slechts een verwaarloosbaar deel van de waarden kan proberen in niet-belachelijke tijd1.

Unieke identifiers zoals willekeurige UUIDhebben 122 bits van entropie (dwz 2^122 = 5,3×10^36) – de kans op een botsing is “*(…) om een kans van één op een miljard op duplicatie te hebben, moeten 103 biljoen versie 4 UUID’s worden gegenereerd2“. We zullen 128 bits kiezen omdat het precies in 16 bytes pasten wordt gezien als zeer voldoendeom uniek te zijn voor in principe elke, maar de meest extreme, gebruikssituatie en dat hoeft niet denk aan duplicaten. Hier is een eenvoudige vergelijkingstabel van entropie, inclusief eenvoudige analyse van het verjaardagsprobleem.

Voor eenvoudige vereisten kan een lengte van 8 of 12 bytes voldoende zijn, maar met 16 bytes zit u aan de “veilige kant”.

En dat is het eigenlijk. Het laatste is om na te denken over codering, zodat het kan worden weergegeven als een afdrukbare tekst (lees, een String).

3. Codering van binair naar tekst

Typische coderingen zijn onder meer:

  • Base64elk teken codeert 6 bit, het creëren van een overhead van 33%. Gelukkig zijn er standaard implementaties in Java 8+en Android. Met oudere Java kunt u elk van de talloze bibliotheken van derdengebruiken. Als u wilt dat uw tokens URL-veilig zijn, gebruikt u de URL-veilige-versie van RFC4648 ( die meestal wordt ondersteund door de meeste implementaties). Voorbeeldcodering van 16 bytes met opvulling: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32elk teken codeert 5 bit, het creëren van een overhead van 40%. Dit maakt gebruik van A-Zen 2-7, waardoor het redelijk ruimtebesparend is en hoofdletterongevoelig alfanumeriek is. Er is geen standaardimplementatie in de JDK. Voorbeeldcodering van 16 bytes zonder opvulling: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16(hexadecimaal) elk teken codeert vier bits, waarvoor twee tekens per byte nodig zijn (dwz 16 bytes creëren een string met een lengte van 32). Daarom is hexadecimaal minder ruimtebesparend dan Base32, maar het is in de meeste gevallen veilig om te gebruiken (URL) omdat het alleen 0-9en Anaar F. Voorbeeldcodering van 16 bytes: 4fa3dd0f57cb3bf331441ed285b27735. Bekijk hier een Stack Overflow-discussie over converteren naar hexadecimaal.

Extra coderingen zoals Base85en het exotische Base122bestaan met betere/slechtere ruimte-efficiëntie. Je kunt je eigen codering maken (wat in feite de meeste antwoorden in deze thread doen), maar ik zou het afraden als je geen erg specifieke vereisten hebt. Zie meer coderingsschema’s in het Wikipedia-artikel.

4. Samenvatting en voorbeeld

  • Gebruik SecureRandom
  • Gebruik ten minste 16 bytes (2 ^ 128) van mogelijke waarden
  • coderen volgens uw vereisten (meestal hexof base32Als u het nodig hebt om alfa-numeriek te zijn)

niet

  • … Gebruik uw woningbrouwcodering: Beter onderhoudbaar en leesbaar voor anderen als ze zien welke standaardcodering u gebruikt in plaats van rare voor lussen die tekens tegelijk maken.
  • … Gebruik UUID: Het heeft geen garanties op willekeur; U verspilt 6 bits van entropie en heeft een uitgebreide reekstrepresentatie

Voorbeeld: hexadecimale 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); // Hexadecimal encoding
}
//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

Voorbeeld: base64-token-generator (URL-veilig)

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

Voorbeeld: Java CLI-tool

Als u een handelsklare CLI-tool wilt gebruiken, kunt u dobbelstenen :

Voorbeeld: gerelateerd probleem – Bescherm uw huidige ID’s

Als je al een id hebt die je kunt gebruiken (bijvoorbeeld een synthetische longin je entiteit), maar wil je de interne waarde niet publiceren, je kunt deze bibliotheek gebruiken om deze te coderen en te verdoezelen: https://github.com/patrickfav/id-mask

IdMask<Long> idMask = IdMasks.forLongIds(Config.builder(key).build());
String maskedId = idMask.mask(id);
// Example: NPSBolhMyabUBdTyanrbqT8
long originalId = idMask.unmask(maskedId);

Antwoord 8, autoriteit 3%

Het gebruik van Dollarzou zo eenvoudig moeten zijn als:

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

Het geeft zoiets als dit weer:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

Antwoord 9, autoriteit 2%

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

Hier is een voorbeeldrun:

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

Antwoord 10, autoriteit 2%

Een korte en gemakkelijke oplossing, maar er worden alleen kleine letters en cijfers gebruikt:

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

De grootte is ongeveer 12 cijfers tot basis 36 en kan op die manier niet verder worden verbeterd. Natuurlijk kunt u meerdere instanties toevoegen.


Antwoord 11, autoriteit 2%

Verrassend genoeg heeft niemand hier het gesuggereerd, maar:

import java.util.UUID
UUID.randomUUID().toString();

Eenvoudig.

Het voordeel hiervan is dat UUID’s mooi, lang zijn en gegarandeerd bijna onmogelijk te botsen zijn.

Wikipedia heeft een goede uitlegervan:

” …alleen na het genereren van 1 miljard UUID’s per seconde gedurende de komende 100 jaar, zou de kans om slechts één duplicaat te maken ongeveer 50% zijn.”

De eerste vier bits zijn het versietype en twee voor de variant, dus u krijgt 122 stukjes willekeurig. Dus als u wilt aan, kunt u vanaf het einde afkappen om de grootte van de UUID te verminderen. Het wordt niet aanbevolen, maar je hebt nog steeds veel willekeurige willekeurige, genoeg voor je 500k records eenvoudig.


Antwoord 12

Een alternatief in Java 8 is:

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

Antwoord 13

import java.util.Random;
public class passGen{
    // Version 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 StringBuilder pass = new StringBuilder();
    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(26);
                pass.append(dCase.charAt(spot));
            } else if (rPick == 1) {
                int spot = r.nextInt(26);
                pass.append(uCase.charAt(spot));
            } else if (rPick == 2) {
                int spot = r.nextInt(8);
                pass.append(sChar.charAt(spot));
            } else {
                int spot = r.nextInt(10);
                pass.append(intChar.charAt(spot));
            }
        }
        System.out.println ("Generated Pass: " + pass.toString());
    }
}

Dit voegt gewoon het wachtwoord toe aan de string en… ja, het werkt goed. Check it out… Het is heel eenvoudig; Ik heb het geschreven.


Antwoord 14

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

Antwoord 15

Het gebruik van UUID’s is onveilig, omdat delen van de UUID helemaal niet willekeurig zijn. De procedure van ericksonis erg netjes, maar het creëert geen strings van dezelfde lengte. Het volgende fragment zou voldoende moeten zijn:

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

Waarom kiezen length*5? Laten we aannemen dat het simpele geval van een willekeurige reeks van lengte 1, dus één willekeurig karakter. Om een ​​willekeurig karakter te krijgen met alle cijfers van 0-9 en tekens A-Z, zouden we een willekeurig getal tussen 0 en 35 nodig hebben om een ​​van elk teken te krijgen.

BigIntegerBiedt een constructor om een ​​willekeurig getal te genereren, uniform verdeeld over het bereik 0 to (2^numBits - 1). Helaas is 35 geen nummer dat kan worden ontvangen door 2 ^ Numbits – 1.

Dus we hebben twee opties: ingaan met 2^5-1=31of 2^6-1=63. Als we zouden kiezen 2^6zouden we veel “onnodige” / “langere” nummers krijgen. Daarom is 2^5de betere optie, zelfs als we vier personages verliezen (W-Z). Om nu een reeks van een bepaalde lengte te genereren, kunnen we eenvoudig een 2^(length*numBits)-1nummer gebruiken. Het laatste probleem, als we een tekenreeks met een bepaalde lengte willen, kan willekeurig een klein aantal genereren, dus de lengte is niet voldaan, dus we moeten de reeks op de vereiste lengte van de lengte bijbereiden.


Antwoord 16

Ik vond deze oplossing die een willekeurige zes-gecodeerde reeks genereert. De meegeleverde eenheidstest lijkt te houden aan mijn primaire gebruikscase. Hoewel, het is iets complexer dan sommige van de andere verstrekte antwoorden.

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

Antwoord 17

  1. Wijzig String-tekens volgens uw vereisten.

  2. String is onveranderlijk. Hier is StringBuilder.appendefficiënter dan het samenvoegen van tekenreeksen.

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

Antwoord 18

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

Antwoord 19

Ik hou niet echt van deze antwoorden met betrekking tot een “eenvoudige” oplossing: S

Ik zou gaan voor een eenvoudige ;), pure Java, één voering (entropie is gebaseerd op willekeurige tekenreekslengte en de gegeven tekenset):

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")); // The character set can basically be anything
    }
}

Of (een beetje beter leesbaar op de oude manier)

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")); // The character set can basically be anything
    }
}

Maar aan de andere kant zou je ook kunnen gaan met UUIDdie een mooie goede entropie:

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

Antwoord 20

Ik gebruik een bibliotheek van Apache Commonsom een alfanumerieke tekenreeks te genereren:

import org.apache.commons.lang3.RandomStringUtils;
String keyLength = 20;
RandomStringUtils.randomAlphanumeric(keylength);

Het is snel en eenvoudig!


Antwoord 21

U noemt “eenvoudig”, maar voor het geval iemand anders op zoek is naar iets dat aan strengere beveiligingseisen voldoet, kunt u een kijkje nemen op jpwgen. jpwgen is gemodelleerd naar pwgenin Unix, en is zeer configureerbaar.


Antwoord 22

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

Antwoord 23

U kunt de volgende code gebruiken, als uw wachtwoord verplicht cijfers en alfabetische speciale tekens bevat:

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

Antwoord 24

Je kunt de UUID-klasse met zijn getLeastSignificantBits()-bericht gebruiken om 64 bits willekeurige-gegevens te krijgen, en deze vervolgens converteren naar een radix 36-nummer (dwz een tekenreeks die bestaat uit 0-9,AZ ):

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

Dit levert een tekenreeksop van maximaal 13 tekens. We gebruiken Math.abs() om ervoor te zorgen dat er geen minteken binnensluipt.


Antwoord 25

Hier is de oneliner van AbacusUtil:

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

Willekeurig betekent niet dat het uniek moet zijn. Gebruik om unieke strings te krijgen:

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

Antwoord 26

Hier is het een Scala-oplossing:

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

Antwoord 27

Met behulp van een Apache Commons-bibliotheek kan dit in één regel worden gedaan:

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

Documentatie


Antwoord 28

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

Antwoord 29

Ik denk dat dit hier de kleinste oplossing is, of bijna een van de kleinste:

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

De code werkt prima. Als u deze methode gebruikt, raad ik u aan meer dan 10 tekens te gebruiken. Een botsing vindt plaats bij 5 karakters / 30362 iteraties. Dit duurde 9 seconden.


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

Other episodes