Frage

Ich habe nach einem gesucht einfach Java-Algorithmus zum Generieren einer pseudozufälligen alphanumerischen Zeichenfolge.In meiner Situation würde es als eindeutige Sitzungs-/Schlüsselkennung verwendet werden, die „wahrscheinlich“ eindeutig wäre 500K+ Generation (meine Bedürfnisse erfordern eigentlich nichts viel Anspruchsvolleres).

Im Idealfall könnte ich je nach meinen Einzigartigkeitsanforderungen eine Länge angeben.Eine generierte Zeichenfolge mit der Länge 12 könnte beispielsweise so aussehen: "AEYGF7K0DM1X".

War es hilfreich?

Lösung

Algorithmus

Um eine zufällige Zeichenfolge zu generieren, verketten Sie zufällig aus dem Satz akzeptabler Symbole gezogene Zeichen, bis die Zeichenfolge die gewünschte Länge erreicht.

Implementierung

Hier ist ein ziemlich einfacher und sehr flexibler Code zum Generieren zufälliger Bezeichner. Lesen Sie die folgenden Informationen für wichtige Anwendungshinweise.

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

}

Anwendungsbeispiele

Erstellen Sie einen unsicheren Generator für 8-stellige Bezeichner:

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

Erstellen Sie einen sicheren Generator für Sitzungskennungen:

RandomString session = new RandomString();

Erstellen Sie einen Generator mit leicht lesbaren Codes zum Drucken.Die Zeichenfolgen sind länger als vollständige alphanumerische Zeichenfolgen, um die Verwendung weniger Symbole auszugleichen:

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

Verwendung als Sitzungskennungen

Das Generieren von Sitzungskennungen, die wahrscheinlich eindeutig sind, reicht nicht aus, oder Sie könnten einfach einen einfachen Zähler verwenden.Angreifer kapern Sitzungen, wenn vorhersehbare Identifikatoren verwendet werden.

Es besteht ein Spannungsverhältnis zwischen Länge und Sicherheit.Kürzere Bezeichner sind leichter zu erraten, da es weniger Möglichkeiten gibt.Längere Kennungen verbrauchen jedoch mehr Speicher und Bandbreite.Ein größerer Satz an Symbolen ist hilfreich, kann jedoch zu Codierungsproblemen führen, wenn Bezeichner in URLs enthalten oder manuell erneut eingegeben werden.

Die zugrunde liegende Quelle der Zufälligkeit oder Entropie für Sitzungskennungen sollte von einem Zufallszahlengenerator stammen, der für die Kryptografie entwickelt wurde.Allerdings kann die Initialisierung dieser Generatoren manchmal rechenintensiv oder langsam sein, daher sollte versucht werden, sie nach Möglichkeit wiederzuverwenden.

Verwendung als Objektbezeichner

Nicht jede Anwendung erfordert Sicherheit.Die zufällige Zuweisung kann für mehrere Entitäten eine effiziente Möglichkeit sein, Bezeichner in einem gemeinsam genutzten Raum ohne Koordination oder Partitionierung zu generieren.Die Koordination kann langsam sein, insbesondere in einer geclusterten oder verteilten Umgebung, und die Aufteilung eines Bereichs führt zu Problemen, wenn Entitäten am Ende zu kleine oder zu große Anteile haben.

Identifikatoren, die generiert werden, ohne Maßnahmen zu ergreifen, um sie unvorhersehbar zu machen, sollten auf andere Weise geschützt werden, wenn ein Angreifer sie möglicherweise anzeigen und manipulieren könnte, wie dies bei den meisten Webanwendungen der Fall ist.Es sollte ein eigenes Autorisierungssystem geben, das Objekte schützt, deren Kennung von einem Angreifer ohne Zugriffsberechtigung erraten werden kann.

Es muss außerdem darauf geachtet werden, dass die Bezeichner lang genug sind, um angesichts der erwarteten Gesamtzahl der Bezeichner Kollisionen unwahrscheinlich zu machen.Dies wird als „Geburtstagsparadoxon“ bezeichnet. Die Wahrscheinlichkeit einer Kollision, P, ist ungefähr n2/(2qX), Wo N ist die Anzahl der tatsächlich generierten Identifikatoren, Q ist die Anzahl der unterschiedlichen Symbole im Alphabet und X ist die Länge der Bezeichner.Dies sollte eine sehr kleine Zahl sein, z. B. 2‑50 oder weniger.

Die Berechnung zeigt, dass die Wahrscheinlichkeit einer Kollision zwischen 500.000 15-stelligen Bezeichnern etwa 2 beträgt‑52, was wahrscheinlich weniger wahrscheinlich ist als unentdeckte Fehler durch kosmische Strahlung usw.

Vergleich mit UUIDs

Gemäß ihrer Spezifikation sind UUIDs nicht darauf ausgelegt, unvorhersehbar zu sein sollte nicht als Sitzungskennungen verwendet werden.

UUIDs in ihrem Standardformat nehmen viel Platz ein:36 Zeichen für nur 122 Bit Entropie.(Nicht alle Bits einer „zufälligen“ UUID werden zufällig ausgewählt.) Eine zufällig ausgewählte alphanumerische Zeichenfolge bietet mehr Entropie in nur 21 Zeichen.

UUIDs sind nicht flexibel;Sie haben eine standardisierte Struktur und Anordnung.Dies ist sowohl ihre größte Tugend als auch ihre größte Schwäche.Bei der Zusammenarbeit mit einer externen Partei kann die durch UUIDs gebotene Standardisierung hilfreich sein.Für den rein internen Gebrauch können sie ineffizient sein.

Andere Tipps

Java bietet eine Möglichkeit, dies direkt zu tun.Wenn Sie die Striche nicht möchten, können Sie sie einfach entfernen.Benutz einfach 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;
    }
}

Ausgabe:

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

Wenn Sie gerne Apache-Klassen verwenden, können Sie Folgendes verwenden org.apache.commons.text.RandomStringGenerator (Commons-Text).

Beispiel:

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

Seit commons-lang 3.6, RandomStringUtils ist veraltet.

In einer Zeile:

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

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

Sie können hierfür die Apache-Bibliothek verwenden: RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

Dies ist ohne externe Bibliotheken leicht zu erreichen.

1.Kryptografische pseudozufällige Datengenerierung

Zuerst benötigen Sie ein kryptografisches PRNG.Java hat SecureRandom Dafür wird normalerweise die beste Entropiequelle auf der Maschine verwendet (z. B. /dev/random) . Lesen Sie hier mehr.

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

Notiz: SecureRandom ist die langsamste, aber sicherste Methode in Java, zufällige Bytes zu generieren.Ich empfehle jedoch, die Leistung hier NICHT zu berücksichtigen, da sie normalerweise keine wirklichen Auswirkungen auf Ihre Anwendung hat, es sei denn, Sie müssen Millionen von Token pro Sekunde generieren.

2.Benötigter Platz möglicher Werte

Als nächstes müssen Sie entscheiden, „wie einzigartig“ Ihr Token sein soll.Der einzige und einzige Sinn der Entropiebetrachtung besteht darin, sicherzustellen, dass das System Brute-Force-Angriffen widerstehen kann:Der Raum möglicher Werte muss so groß sein, dass ein Angreifer in nicht lächerlicher Zeit nur einen vernachlässigbaren Teil der Werte ausprobieren kann1.Eindeutige Bezeichner, z. B. „random“. UUID haben 122 Bit Entropie (d. h.2^122 = 5,3x10^36) – die Wahrscheinlichkeit einer Kollision beträgt „*(...) Damit die Wahrscheinlichkeit einer Duplizierung bei eins zu einer Milliarde liegt, müssen 103 Billionen UUIDs der Version 4 generiert werden2". Wir wählen 128 Bit, da es genau in 16 Bytes passt und wird als angesehen absolut ausreichend dafür, dass es praktisch für alle, aber auch die extremsten Anwendungsfälle einzigartig ist und Sie nicht über Duplikate nachdenken müssen.Hier ist eine einfache Vergleichstabelle der Entropie einschließlich einer einfachen Analyse der Geburtstagsproblem.

comparison of token sizes

Für einfache Anforderungen reichen vielleicht 8 oder 12 Byte Länge, mit 16 Byte ist man aber auf der „sicheren Seite“.

Und das ist es im Grunde.Als letztes müssen Sie über die Codierung nachdenken, damit sie als druckbarer Text dargestellt werden kann (lesen Sie, a String).

3.Binär-zu-Text-Kodierung

Typische Kodierungen sind:

  • Base64 Jedes Zeichen wird mit 6 Bit codiert, wodurch ein Overhead von 33 % entsteht.Glücklicherweise gibt es Standardimplementierungen Java 8+ Und Android.Mit älterem Java können Sie jedes davon verwenden zahlreiche Bibliotheken Dritter.Wenn Sie möchten, dass Ihre Token URL-sicher sind, verwenden Sie die URL-sicher Version von RFC4648 (die normalerweise von den meisten Implementierungen unterstützt wird).Beispiel für die Codierung von 16 Bytes mit Auffüllung: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 Jedes Zeichen kodiert 5 Bit, was einen Overhead von 40 % verursacht.Dies wird verwendet A-Z Und 2-7 Dies macht es einigermaßen platzsparend und berücksichtigt gleichzeitig die Groß- und Kleinschreibung bei alphanumerischen Zeichen.Es gibt kein Standardimplementierung im JDK.Beispiel für die Codierung von 16 Bytes ohne Auffüllung: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (hex) Jedes Zeichen kodiert 4 Bit, was 2 Zeichen pro Byte erfordert (d. h.16 Byte erzeugen einen String der Länge 32).Daher ist Hex weniger platzsparend als Base32 ist aber in den meisten Fällen sicher zu verwenden (URL), da es nur verwendet wird 0-9 Und A Zu F.Beispiel für die Codierung von 16 Bytes: 4fa3dd0f57cb3bf331441ed285b27735. Eine SO-Diskussion über die Konvertierung in Hex finden Sie hier.

Zusätzliche Kodierungen wie Base85 und das Exotische Basis122 existieren mit besserer/schlechterer Raumeffizienz.Sie können Ihre eigene Codierung erstellen (was im Grunde genommen bei den meisten Antworten in diesem Thread der Fall ist), ich würde jedoch davon abraten, wenn Sie keine sehr spezifischen Anforderungen haben.Sehen Weitere Codierungsschemata im Wikipedia-Artikel.

4.Zusammenfassung und Beispiel

  • Verwenden SecureRandom
  • Verwenden Sie mindestens 16 Byte (2^128) möglicher Werte
  • Codieren Sie entsprechend Ihren Anforderungen (normalerweise hex oder base32 wenn es alphanumerisch sein soll)

Nicht

  • ...Verwenden Sie Ihre Homebrew-Kodierung: Besser wartbar und für andere lesbar, wenn sie sehen, welche Standardcodierung Sie verwenden, anstatt seltsame For-Schleifen, die gleichzeitig Zeichen erstellen.
  • ...UUID verwenden: es gibt keine Garantien für die Zufälligkeit;Sie verschwenden 6 Bit Entropie und haben eine ausführliche Zeichenfolgendarstellung

Beispiel: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

Beispiel:Base64-Token-Generator (URL-sicher)

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

Beispiel:Java CLI-Tool

Wenn Sie ein gebrauchsfertiges CLI-Tool wünschen, können Sie Dice verwenden: https://github.com/patrickfav/dice

verwenden Dollar sollte einfach sein wie:

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

es gibt etwa so etwas aus:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

Hier ist es 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 ist ein Beispiellauf:

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

Überraschenderweise hat es hier niemand vorgeschlagen, aber:

import java.util.UUID

UUID.randomUUID().toString();

Einfach.

Dies hat den Vorteil, dass UUIDs schön lang sind und eine Kollision garantiert nahezu unmöglich ist.

Wikipedia hat eine gute Erklärung dazu:

„...nur wenn in den nächsten 100 Jahren 1 Milliarde UUIDs pro Sekunde generiert werden, liegt die Wahrscheinlichkeit, nur ein Duplikat zu erstellen, bei etwa 50 %.“

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

Die ersten 4 Bits sind der Versionstyp und 2 für die Variante, sodass Sie 122 Zufallsbits erhalten.Also wenn du wollen Sie können vom Ende an abschneiden, um die Größe der UUID zu reduzieren.Es wird nicht empfohlen, aber Sie haben immer noch viel Zufälligkeit, genug für Ihre 500.000 Datensätze.

Eine kurze und einfache Lösung, die jedoch nur Kleinbuchstaben und Ziffern verwendet:

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

Die Größe beträgt etwa 12 Stellen zur Basis 36 und kann auf diese Weise nicht weiter verbessert werden.Natürlich können Sie mehrere Instanzen anhängen.

Eine Alternative in Java 8 ist:

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

Die Verwendung von UUIDs ist unsicher, da Teile der UUID überhaupt nicht zufällig sind.Das Verfahren von @erickson ist sehr ordentlich, erzeugt aber keine Strings gleicher Länge.Der folgende Ausschnitt sollte ausreichen:

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

Warum wählen length*5.Nehmen wir den einfachen Fall einer zufälligen Zeichenfolge der Länge 1, also eines zufälligen Zeichens, an.Um ein zufälliges Zeichen zu erhalten, das alle Ziffern 0–9 und die Zeichen a–z enthält, benötigen wir eine Zufallszahl zwischen 0 und 35, um von jedem Zeichen eines zu erhalten. BigInteger stellt einen Konstruktor zum Generieren einer Zufallszahl bereit, die gleichmäßig über den Bereich verteilt ist 0 to (2^numBits - 1).Leider ist 35 keine Zahl, die von 2^numBits - 1 empfangen werden kann.Wir haben also zwei Möglichkeiten:Entweder geh mit 2^5-1=31 oder 2^6-1=63.Wenn wir wählen würden 2^6 wir würden viele „unnötige“/„längere“ Zahlen bekommen.daher 2^5 ist die bessere Option, auch wenn wir 4 Zeichen (w-z) verlieren.Um nun einen String mit einer bestimmten Länge zu generieren, können wir einfach a verwenden 2^(length*numBits)-1 Nummer.Das letzte Problem: Wenn wir eine Zeichenfolge mit einer bestimmten Länge benötigen, könnte der Zufallsgenerator eine kleine Zahl generieren, sodass die Länge nicht erreicht wird. Daher müssen wir die Zeichenfolge auf die erforderliche Länge auffüllen und Nullen voranstellen.

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

Was dies also bewirkt, ist, einfach das Passwort in die Zeichenfolge einzufügen und ...Ja, funktioniert gut, schau es dir an...sehr einfach.ich schrieb es

Ich habe diese Lösung gefunden, die eine zufällige hexadezimal codierte Zeichenfolge generiert.Der bereitgestellte Unit-Test scheint meinem primären Anwendungsfall standzuhalten.Allerdings ist sie etwas komplexer als einige der anderen Antworten.

/**
 * 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. Ändern Sie die Zeichenfolgenzeichen entsprechend Ihren Anforderungen.

  2. String ist unveränderlich.Hier StringBuilder.append ist effizienter als die String-Verkettung.


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

Mir gefällt keine dieser Antworten bezüglich der „einfachen“ Lösung wirklich :S

Ich würde mich für ein einfaches ;), reines Java, einen Liner entscheiden (die Entropie basiert auf der zufälligen Stringlänge und dem gegebenen Zeichensatz):

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

oder (etwas besser lesbarer, alter Weg)

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

Andererseits könnten Sie aber auch eine UUID verwenden, die eine ziemlich gute Entropie aufweist (https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions):

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

Hoffentlich hilft das.

Sie erwähnen „einfach“, aber für den Fall, dass jemand anderes nach etwas sucht, das strengere Sicherheitsanforderungen erfüllt, sollten Sie einen Blick darauf werfen jpwgen.jpwgen ist nachempfunden pwgen unter Unix und ist sehr konfigurierbar.

Hier ist es eine Scala-Lösung:

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

Sie können die UUID-Klasse mit ihrer getLeastSignificantBits()-Nachricht verwenden, um 64-Bit-Zufallsdaten abzurufen und diese dann in eine Basiszahl von 36 umzuwandeln (d. h.eine Zeichenfolge bestehend aus 0-9,A-Z):

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

Dies ergibt einen String mit einer Länge von bis zu 13 Zeichen.Wir verwenden Math.abs(), um sicherzustellen, dass sich kein Minuszeichen einschleicht.

Sie können den folgenden Code verwenden, wenn Ihr Passwort zwingend Zahlen, alphabetische Sonderzeichen enthält:

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

}

Hier ist der einzeilige Code von AbacusUtil

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

Zufällig bedeutet nicht, dass es einzigartig sein muss.um eindeutige Zeichenfolgen zu erhalten, verwenden Sie:

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

Mit der Apache-Bibliothek kann dies in einer Zeile erfolgen

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

Hier ist Doc 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;
}

Ich denke, das ist hier die kleinste Lösung, oder fast eine der kleinsten:

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

Der Code funktioniert einwandfrei.Wenn Sie diese Methode verwenden, empfehle ich Ihnen, mehr als 10 Zeichen zu verwenden.Eine Kollision tritt bei 5 Zeichen/30362 Iterationen auf.Dies dauerte 9 Sekunden.

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

Vielleicht ist das hilfreich

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;

    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top