Die Verwendung von UUIDs ist unsicher, da Teile der UUIDs nicht zufällig sind. Die verfahren von erickson ist sehr ordentlich, aber es erzeugt keine Zeichenketten mit gleicher Länge. Das folgende Snippet sollte ausreichend sein:
/*
* 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 Zeichenkette der Länge 1 an, also ein zufälliges Zeichen. Um ein Zufallszeichen zu erhalten, das alle Ziffern 0-9 und die Buchstaben a-z enthält, bräuchten wir eine Zufallszahl zwischen 0 und 35, um von jedem Zeichen eines zu erhalten.
BigInteger
bietet einen Konstruktor zur Erzeugung einer Zufallszahl, 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 wir nehmen 2^5-1=31
o 2^6-1=63
. Wenn wir wählen würden 2^6
würden wir eine Menge "unnötiger" / "längerer" Nummern erhalten. Deshalb 2^5
ist die bessere Option, auch wenn wir vier Zeichen (w-z) verlieren. Um nun eine Zeichenkette einer bestimmten Länge zu erzeugen, können wir einfach eine 2^(length*numBits)-1
Nummer. Das letzte Problem ist, dass, wenn wir eine Zeichenkette mit einer bestimmten Länge haben wollen, der Zufallsgenerator eine kleine Zahl erzeugen könnte, so dass die Länge nicht erreicht wird, so dass wir die Zeichenkette auf die gewünschte Länge auffüllen müssen, indem wir Nullen voranstellen.
166 Stimmen
Vorsicht das Geburtstagsparadoxon .
64 Stimmen
Selbst wenn man das Geburtstagsparadoxon in Betracht zieht, bräuchte man bei Verwendung von 12 alphanumerischen Zeichen (62 insgesamt) immer noch weit über 34 Milliarden Zeichenfolgen, um das Paradoxon zu erreichen. Und das Geburtstagsparadoxon garantiert sowieso keine Kollision, es sagt nur, dass die Wahrscheinlichkeit über 50 % liegt.
6 Stimmen
@NullUserException 50 % Erfolgschance (pro Versuch) ist verdammt hoch: Selbst bei 10 Versuchen liegt die Erfolgsquote bei 0,999. Wenn man das und die Tatsache bedenkt, dass man innerhalb von 24 Stunden VIELE Versuche machen kann, braucht man keine 34 Milliarden Zeichenfolgen, um ziemlich sicher zu sein, dass man mindestens eine davon errät. Das ist der Grund, warum einige Sitzungs-Tokens sehr, sehr lang sein sollten.
0 Stimmen
Dieser Blogpost sollte nützlich sein - Code zur Erzeugung alphanumerischer Zeichenfolgen: rationaljava.com/2015/06/
20 Stimmen
Diese 3 einzeiligen Codes sind sehr nützlich, schätze ich.
Long.toHexString(Double.doubleToLongBits(Math.random()));
UUID.randomUUID().toString();
RandomStringUtils.randomAlphanumeric(12);
26 Stimmen
@Pijusn Ich weiß, das ist alt, aber... die "50% Chance" im Geburtstagsparadoxon ist NO "pro Versuch", das heißt "50 % Wahrscheinlichkeit, dass von (in diesem Fall) 34 Milliarden Zeichenfolgen mindestens ein Paar Dubletten vorhanden ist". Sie bräuchten 1,6 sept illionen - 1,6e21 - Einträge in Ihrer Datenbank, um eine Chance von 50% pro Versuch zu haben.
0 Stimmen
Es ist besser, die
"-"
in der Zeichenkette0 Stimmen
Zufällige Zeichenkette mit Javascript, Java, Python, Rust, Bash