Frage Generieren Sie zufällige Zeichenfolgen in JavaScript


Ich möchte eine 5-stellige Zeichenfolge, die aus zufällig ausgewählten Zeichen besteht [a-zA-Z0-9].

Was ist der beste Weg, dies mit JavaScript zu tun?


1151
2017-08-28 21:14


Ursprung


Antworten:


Ich denke, das wird für Sie funktionieren:

function makeid() {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < 5; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));

  return text;
}

console.log(makeid());


1637
2017-08-28 21:21



Math.random().toString(36).substring(7);

1726
2017-11-10 18:12



Math.random ist schlecht für diese Art von Sache

Option 1

Wenn du das kannst Server-Seite, benutze einfach die Krypto Modul

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

Die resultierende Zeichenfolge ist doppelt so lang wie die zufälligen Bytes, die Sie generieren. Jedes in hexadezimale Byte codierte Byte besteht aus 2 Zeichen. 20 Bytes sind 40 Zeichen von Hex.


Option 2

Wenn du das tun musst Klient-Seite, vielleicht versuchen Sie das Uuid-Modul

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

Option 3

Wenn du das tun musst Klient-Seite und Sie müssen keine alten Browser unterstützen, Sie können es ohne Abhängigkeiten tun

// dec2hex :: Integer -> String
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"


238
2018-01-02 19:18



Hier ist eine Verbesserung Doubletap's ausgezeichnete Antwort. Das Original hat zwei Nachteile, die hier angesprochen werden:

Erstens, wie andere bereits erwähnt haben, hat es eine geringe Wahrscheinlichkeit, kurze Strings oder sogar eine leere Zeichenfolge zu erzeugen (wenn die Zufallszahl 0 ist), was Ihre Anwendung beschädigen kann. Hier ist eine Lösung:

(Math.random().toString(36)+'00000000000000000').slice(2, N+2)

Zweitens begrenzen sowohl das Original als auch die obige Lösung die Zeichenkettengröße N auf 16 Zeichen. Im Folgenden wird eine Zeichenfolge der Größe N für jedes N zurückgegeben (beachten Sie jedoch, dass die Verwendung von N> 16 die Zufälligkeit nicht erhöht oder die Wahrscheinlichkeit von Kollisionen verringert):

Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)

Erläuterung:

  1. Wählen Sie eine Zufallszahl im Bereich [0,1], d. H. Zwischen 0 (einschließlich) und 1 (exklusiv).
  2. Konvertiere die Zahl in eine Basis-36-Zeichenfolge, d. H. Unter Verwendung der Zeichen 0-9 und a-z.
  3. Pad mit Nullen (löst die erste Ausgabe).
  4. Schneiden Sie die führende '0' ab. Präfix und zusätzliche Auffüll-Nullen.
  5. Wiederholen Sie die Zeichenfolge so oft, dass mindestens N Zeichen enthalten sind (indem Sie leere Zeichenfolgen mit der kürzeren zufälligen Zeichenfolge verbinden, die als Trennzeichen verwendet wird).
  6. Schneiden Sie genau N Zeichen aus der Zeichenfolge.

Weitere Gedanken:

  • Diese Lösung verwendet keine Großbuchstaben, aber in fast allen Fällen (kein Wortspiel beabsichtigt) spielt es keine Rolle.
  • Die maximale Stringlänge bei N = 16 in der ursprünglichen Antwort wird in Chrome gemessen. In Firefox ist es N = 11. Aber wie bereits erwähnt, geht es bei der zweiten Lösung darum, die Länge der angeforderten Strings zu unterstützen, und nicht darum, Zufälligkeiten hinzuzufügen. Es macht also keinen großen Unterschied.
  • Alle zurückgegebenen Strings haben eine gleiche Wahrscheinlichkeit, dass sie zurückgegeben werden, zumindest soweit die von Math.random () zurückgegebenen Ergebnisse gleichmäßig verteilt sind (dies ist in jedem Fall keine Kryptographie-Stärke-Zufälligkeit).
  • Es können nicht alle möglichen Zeichenfolgen der Größe N zurückgegeben werden. Bei der zweiten Lösung ist dies offensichtlich (da die kleinere Zeichenfolge einfach dupliziert wird), aber dies gilt auch in der ursprünglichen Antwort, da bei der Umwandlung in die Basis 36 die letzten paar Bits möglicherweise nicht Teil der ursprünglichen Zufallsbits sind. Wenn Sie sich das Ergebnis von Math.random (). ToString (36) anschauen, werden Sie feststellen, dass das letzte Zeichen nicht gleichmäßig verteilt ist. Auch hier spielt es in fast allen Fällen keine Rolle, aber wir schneiden die letzte Zeichenfolge vom Anfang an statt vom Ende der zufälligen Zeichenfolge ab, so dass kurze Zeichenfolgen (z. B. N = 1) nicht betroffen sind.

Aktualisieren:

Hier sind ein paar andere funktionale Ein-Liner, die ich mir ausgedacht habe. Sie unterscheiden sich von der obigen Lösung dadurch, dass

  • Sie verwenden ein explizites willkürliches Alphabet (allgemeiner und passend zur ursprünglichen Frage, die sowohl Groß- als auch Kleinbuchstaben verlangt).
  • Alle Ketten der Länge N haben eine gleiche Wahrscheinlichkeit, dass sie zurückgegeben werden (d. H. Ketten enthalten keine Wiederholungen).
  • Sie basieren auf einer Kartenfunktion und nicht auf dem Trick toString (36), wodurch sie einfacher und leichter zu verstehen sind.

Also, sagen Sie, Ihr Alphabet der Wahl ist

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Dann sind diese beiden einander gleich, so dass Sie wählen können, was für Sie intuitiver ist:

Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

und

Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');

Bearbeiten:

Ich sehe so aus Qubyte und Martijn de Milliano kam zu ähnlichen Lösungen (kudos!), die ich irgendwie vermisste. Da sie auf den ersten Blick nicht so kurz aussehen, werde ich sie hier lassen, für den Fall, dass jemand wirklich ein One-Liner möchte :-)

Außerdem wurde "neues Array" durch "Array" in allen Lösungen ersetzt, um ein paar weitere Bytes zu entfernen.


128
2017-11-13 21:18



Kurz, einfach und zuverlässig

Gibt genau 5 zufällige Zeichen zurück, im Gegensatz zu einigen der am häufigsten bewerteten Antworten.

Math.random().toString(36).substr(2, 5);

126
2017-07-27 20:24



So etwas sollte funktionieren

function randomString(len, charSet) {
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var randomString = '';
    for (var i = 0; i < len; i++) {
        var randomPoz = Math.floor(Math.random() * charSet.length);
        randomString += charSet.substring(randomPoz,randomPoz+1);
    }
    return randomString;
}

Rufen Sie mit dem Standardzeichensatz [a-zA-Z0-9] auf oder senden Sie Ihre eigene Nachricht:

var randomValue = randomString(5);

var randomValue = randomString(5, 'PICKCHARSFROMTHISSET');

81
2017-08-28 21:28



function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));


61
2017-08-29 02:41