Genera stringa / caratteri casuali in JavaScript


1780

Voglio una stringa di 5 caratteri composta da personaggi scelti casualmente dal set [a-zA-Z0-9].

Qual è il modo migliore per farlo con JavaScript?


48
Attenzione: nessuna delle risposte ha un true-randomrisultato! Lo sono solo pseudo-random. Quando si utilizzano stringhe casuali per protezione o sicurezza, non usare nessuna di esse !!! Prova una di queste API: random.org
Ron van der Heijden,

48
Math.random (). ToString (36) .replace (/ [^ az] + / g, '')
Muaz Khan

13
Si prega di inserire la soluzione in una soluzione.
chryss,

216
Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
Friedrich,

12
Nota L'API HTML5 per la casualità fornisce la casualità reale.
mikemaccana,

Risposte:


2433

Penso che questo funzionerà per te:

function makeid(length) {
   var result           = '';
   var characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
   var charactersLength = characters.length;
   for ( var i = 0; i < length; i++ ) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
   }
   return result;
}

console.log(makeid(5));


117
Questo va bene per stringhe brevi, ma attenzione, l'uso +=su stringhe come questa provoca un comportamento O (n ^ 2). Se si desidera creare stringhe più lunghe, è necessario creare una matrice di singoli caratteri e unirli alla fine.
dan_waterworth,

97
@dan_waterworth Probabilmente non importa in quasi tutti i casi: codinghorror.com/blog/2009/01/…
Alex Reece,

7
@dan_waterworth, in realtà, +=è spesso più veloce per qualche motivo, anche usato all'interno di loop - jsperf.com/join-vs-concatenation
Konrad Borowski

18
@JonathanPaulson Mostrami i numeri . Vedi il commento precedente con un link jsperf o jsperf.com/sad-tragedy-of-microoptimization o sitepen.com/blog/2008/05/09/string-performance-an-analysis ecc. Inoltre, questa domanda riguarda solo 5 concatenazioni .
Alex Reece,

11
@codenamejames Per favore , non usare questo nella tua password saling. È solo pseudo-casuale non sicuro. Supponendo che tu stia usando Node (non sono nemmeno sicuro da dove cominciare se stai salando sul lato client), usa cryptoinvece.
Hydrothermal

2330

let r = Math.random().toString(36).substring(7);
console.log("random", r);

Nota: l'algoritmo sopra riportato presenta i seguenti punti deboli:

  • Genererà ovunque tra 0 e 6 caratteri a causa del fatto che gli zeri finali vengono rimossi quando si stringono i punti mobili.
  • Dipende profondamente dall'algoritmo utilizzato per stringere i numeri in virgola mobile, che è terribilmente complesso. (Vedi il documento "Come stampare con precisione i numeri in virgola mobile" .)
  • Math.random()può produrre un output prevedibile ("dall'aspetto casuale" ma non realmente casuale) a seconda dell'implementazione. La stringa risultante non è adatta quando è necessario garantire unicità o imprevedibilità.
  • Anche se ha prodotto 6 personaggi uniformemente casuali e imprevedibili, puoi aspettarti di vedere un duplicato dopo aver generato solo circa 50.000 stringhe, a causa del paradosso del compleanno . (sqrt (36 ^ 6) = 46656)

276
Math.random().toString(36).substr(2, 5), perché .substring(7)causa più di 5 caratteri. Punti pieni, ancora!
drago,

81
@Scoop Il toStringmetodo di un tipo di numero in JavaScript utilizza un parametro opzionale per convertire il numero in una data base. Se ne passi due, ad esempio, vedrai il tuo numero rappresentato in binario. Simile all'esagono (base 16), la base 36 utilizza le lettere per rappresentare le cifre oltre 9. Convertendo un numero casuale in base 36, finirai con un gruppo di lettere e numeri apparentemente casuali.
Chris Baker,

76
Sembra bello ma in alcuni casi questo genera una stringa vuota! Se restituisce casuale 0, 0,5, 0,25, 0,125 ... risulterà una stringa vuota o corta.
Gertas,

68
@gertas Questo può essere evitato da(Math.random() + 1).toString(36).substring(7);
George Reith l'

84
Ragazzo, questo è praticamente inutile. Eseguilo solo 1000000 volte e in genere ottieni circa 110000 ricorrenze ripetute: var valori = {}, i = 0, duplicateCount = 0, val; while (i <1000000) {val = Math.random (). toString (36) .substring (7); if (valori [val]) {duplicateCount ++; } valori [val] = 1; i ++; } console.log ("TOTAL DUPLICATES", duplicateCount);
hacklikecrack,

463

Math.random è dannoso per questo tipo di cose

opzione 1

Se riesci a fare questo lato server , usa semplicemente il modulo crypto -

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

// "bb5dc8842ca31d4603d6aa11448d1654"

La stringa risultante sarà lunga il doppio dei byte casuali generati; ogni byte codificato in esadecimale è di 2 caratteri. 20 byte saranno 40 caratteri esadecimali.


opzione 2

Se devi fare questo lato client , forse prova il modulo uuid -

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

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

Opzione 3

Se devi fare questo lato client e non devi supportare i vecchi browser, puoi farlo senza dipendenze -

// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
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"


Per ulteriori informazioni su crypto.getRandomValues-

Il crypto.getRandomValues()metodo consente di ottenere valori casuali crittograficamente forti. L'array fornito come parametro è riempito con numeri casuali (casuale nel suo significato crittografico).

Ecco un piccolo esempio di console:

> var arr = new Uint8Array(4) # make array of 4 bytes (values 0-255)
> arr
Uint8Array(4) [ 0, 0, 0, 0 ]

> window.crypto
Crypto { subtle: SubtleCrypto }

> window.crypto.getRandomValues()
TypeError: Crypto.getRandomValues requires at least 1 argument, but only 0 were passed

> window.crypto.getRandomValues(arr)
Uint8Array(4) [ 235, 229, 94, 228 ]

Per il supporto IE11 è possibile utilizzare -

(window.crypto || window.msCrypto).getRandomValues(arr)

Per la copertura del browser, consultare https://caniuse.com/#feat=getrandomvalues


4
Esattamente. Mentre un UUID va bene per assegnare un ID a una cosa, usarlo come una stringa di caratteri casuali non è una grande idea per questo (e probabilmente altri) motivi.
wmassingham,

2
Non è necessario .map()nell'opzione 3. Array.from(arr, dec2hex).join('')=== Array.from(arr).map(dec2hex).join(''). Grazie per avermi presentato queste funzionalità :-)
Fred Gandt,

6
Dovresti menzionare nella risposta che anche l'opzione 2 ha bisogno di node.js per funzionare, non è javascript puro.
Esko,

5
Pur essendo più crittograficamente sicuro, in realtà non soddisfa i requisiti della domanda perché genera solo 0-9 e af (esadecimali) e non 0-9, az, AZ.
qJake

1
Il requiremodulo non può essere utilizzato solo sul lato server?
aJetHorn,

173

Breve, facile e affidabile

Restituisce esattamente 5 caratteri casuali, al contrario di alcune delle risposte più votate trovate qui.

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

9
Cosa succede se Math.random().toString(36)restituisce un numero con meno di 5 caratteri?
Michael Litvin,

3
Bene, questa è un'accusa interessante da parte di @ Aperçu, non sto dicendo che ho inventato la soluzione, ma la sto usando nei miei progetti ormai da anni. E non ha nulla a che fare con il commento che hai citato. E sono abbastanza sicuro che in SO ciò che conta è l'informazione più utile nel posto giusto e anche se esiste già in qualche altro posto. Fortunatamente, sembra che almeno 51 ragazzi abbiano trovato utile questa risposta, prego!
Silver Ringvee

3
Per evitare di ottenere una stringa vuota in caso di Math.random () restituisce 0, è possibile utilizzarefunction getRandomString() { var result = ''; while (!result) result = Math.random().toString(36).substring(2); return result; };
mikep

5
@rinogo Math.random () può restituire 0 ma non 1 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
mikep

6
Ho eseguito questo codice 1.000.000.000 di volte e non ho ancora ricevuto una stringa vuota: jsfiddle.net/mtp5730r Direi che sei abbastanza sicuro da ottenere una stringa vuota.
MacroMan,

157

Ecco un miglioramento sulla risposta eccellente di doubletap . L'originale presenta due inconvenienti che sono affrontati qui:

In primo luogo, come altri hanno già detto, ha una piccola probabilità di produrre stringhe brevi o persino una stringa vuota (se il numero casuale è 0), che potrebbe interrompere l'applicazione. Ecco una soluzione:

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

In secondo luogo, sia l'originale che la soluzione sopra limitano la dimensione della stringa N a 16 caratteri. Di seguito verrà restituita una stringa di dimensione N per qualsiasi N (ma si noti che l'uso di N> 16 non aumenterà la casualità o diminuirà la probabilità di collisioni):

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

Spiegazione:

  1. Scegli un numero casuale nell'intervallo [0,1), ovvero tra 0 (incluso) e 1 (esclusivo).
  2. Converti il ​​numero in una stringa di base 36, cioè usando i caratteri 0-9 e az.
  3. Pad con zeri (risolve il primo numero).
  4. Taglia il principale '0.' prefisso e zeri di riempimento extra.
  5. Ripeti la stringa abbastanza volte da contenere almeno N caratteri (Unendo le stringhe vuote con la stringa casuale più corta utilizzata come delimitatore).
  6. Taglia esattamente N caratteri dalla stringa.

Ulteriori pensieri:

  • Questa soluzione non utilizza lettere maiuscole, ma in quasi tutti i casi (non è previsto il gioco di parole) non importa.
  • La lunghezza massima della stringa a N = 16 nella risposta originale viene misurata in Chrome. In Firefox è N = 11. Ma, come spiegato, la seconda soluzione riguarda il supporto di qualsiasi lunghezza di stringa richiesta, non l'aggiunta di casualità, quindi non fa molta differenza.
  • Tutte le stringhe restituite hanno la stessa probabilità di essere restituite, almeno nella misura in cui i risultati restituiti da Math.random () sono distribuiti uniformemente (questa non è casualità di forza crittografica, in ogni caso).
  • Non è possibile restituire tutte le stringhe possibili di dimensione N. Nella seconda soluzione questo è ovvio (poiché la stringa più piccola viene semplicemente duplicata), ma anche nella risposta originale ciò è vero poiché nella conversione in base-36 gli ultimi bit potrebbero non far parte dei bit casuali originali. In particolare, se guardi il risultato di Math.random (). ToString (36), noterai che l'ultimo carattere non è distribuito uniformemente. Ancora una volta, in quasi tutti i casi non importa, ma tagliamo la stringa finale dall'inizio piuttosto che la fine della stringa casuale in modo che le stringhe corte (ad es. N = 1) non siano interessate.

Aggiornare:

Qui ci sono un paio di altri one-liner in stile funzionale che ho ideato. Differiscono dalla soluzione sopra in quanto:

  • Usano un alfabeto arbitrario esplicito (più generico e adatto alla domanda originale che chiedeva sia lettere maiuscole che minuscole).
  • Tutte le stringhe di lunghezza N hanno la stessa probabilità di essere restituite (ovvero le stringhe non contengono ripetizioni).
  • Si basano su una funzione della mappa, piuttosto che sul trucco toString (36), che li rende più semplici e facili da capire.

Quindi, supponiamo che il tuo alfabeto preferito sia

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Quindi questi due sono equivalenti tra loro, quindi puoi scegliere quello che è più intuitivo per te:

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

e

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

Modificare:

Mi sembra che il qubyte e Martijn de Milliano abbiano escogitato soluzioni simili a quest'ultima (complimenti!), Che in qualche modo mi mancavano. Dal momento che non sembrano a prima vista, lo lascerò comunque nel caso in cui qualcuno voglia davvero un one-liner :-)

Inoltre, ha sostituito il "nuovo array" con "Array" in tutte le soluzioni per eliminare qualche byte in più.


Perché non aggiungere solo 1? (Math.random()+1).toString(36).substring(7);
emix

Perché l'aggiunta di 1 non risolve nessuno dei due problemi discussi qui. Ad esempio, (1) .toString (36) .substring (7) produce una stringa vuota.
Amichair,

Usando si Math.random().toString(36).substring(2,7)ottiene un risultato atteso che è più simile al.substring(2, n+2)
Joseph Rex del

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

Questo è fantastico, ma quando eseguito in Firefox con N = 16, le ultime ~ 6 cifre finiscono per essere zero ... (Ma soddisfa il desiderio dell'OP di 5 caratteri casuali.)
Edward Newell,

128

La soluzione più compatta, perché sliceè più corta di substring. La sottrazione dall'estremità della stringa consente di evitare il simbolo a virgola mobile generato dalla randomfunzione:

Math.random().toString(36).slice(-5);

o anche

(+new Date).toString(36).slice(-5);

Aggiornamento: aggiunto un altro approccio usando il btoametodo:

btoa(Math.random()).slice(0, 5);
btoa(+new Date).slice(-7, -2);
btoa(+new Date).substr(-7, 5);

// Using Math.random and Base 36:
console.log(Math.random().toString(36).slice(-5));

// Using new Date and Base 36:
console.log((+new Date).toString(36).slice(-5));

// Using Math.random and Base 64 (btoa):
console.log(btoa(Math.random()).slice(0, 5));

// Using new Date and Base 64 (btoa):
console.log(btoa(+new Date).slice(-7, -2));
console.log(btoa(+new Date).substr(-7, 5));


Math.random().toString(36).slice(-5);- Cosa succede se Math.random()ritorna 0.0?
radiografia del

@ radiografia, otterrai "0";)
Valentin Podkamennyi,

2
Esattamente. ;) E se Math.random()restituisce 0.5il risultato è "0.i". Non sono sicuro se ci sono altri casi limite. Volevo solo sottolineare che questa non è una risposta corretta alla domanda (5 caratteri da [a-zA-Z0-9]).
radiografia il

2
@ radiografia, non ho intenzione di dire che questa è la risposta giusta, sto solo dicendo che questa è una versione compatta della risposta @doubletap sopra. Personalmente uso (+new Date + Math.random())per prevenire questo caso. Comunque, grazie per la nota.
Valentin Podkamennyi,

1
Questo. Non so perché altre risposte richiedano così tanto codice
john ktejik

100

Qualcosa del genere dovrebbe funzionare

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

Chiama con il set di caratteri predefinito [a-zA-Z0-9] o invia il tuo:

var randomValue = randomString(5);

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

Una variante di esempio qui può essere trovata qui: mediacollege.com/internet/javascript/number/random.html
David

1
potrebbe anche diminuire lendirettamente in un whileciclo
drzaus

Grazie, ho appena pubblicato di seguito una variante del coffeescript di questo esempio: stackoverflow.com/a/26682781/262379
Dinis Cruz,

Se questi verranno utilizzati pubblicamente, probabilmente dovresti rimuovere le vocali. Un po 'meno entropia, ma molto più sicura in quanto non è possibile generare parole che possano offendere le persone. Ecco perché mi piace questo, poiché posso inviare la mia stringa di caratteri. Buon lavoro.
Nate Bunney,

Abbastanza hardcore, ha funzionato per me, grazie!
Zaki Mohammed,

73

Una versione più recente con operatore di diffusione es6 :

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')

  • È un 30numero arbitrario, puoi scegliere la lunghezza del token che desideri
  • Il 36è il numero massimo radix è possibile passare a numeric.toString () , il che significa che tutti i numeri e le lettere minuscole az
  • Il 2viene utilizzato per raccogliere l'indice 3 ° dalla stringa casuale che assomiglia a questo: "0.mfbiohx64i"potremmo prendere qualsiasi indice dopo0.

Potresti spiegare? Soprattutto perché passi 36 a toString () e perché scegli il 3 ° elemento?
Vuza,

5
questa è la soluzione migliore
superata il

bello, ma questa soluzione non include i caratteri [AZ] come domanda richiesta, solo [a-z0-9]
Nahuel Greco

71

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


Mi piace di più. È possibile modificare facilmente per accettare parametri aggiuntivi e restituire solo numeri, numeri bassi o maiuscoli. Non credo sia necessario lo stile ultra-compressowhile(s.length< L) s+= randomchar();
mastaBlasta,

3
Lo while(L--)farà anche
vsync il

1
Meglio usare il numero più robusto 'A'.charCodeAt(0)piuttosto che magico 55(e allo stesso modo per il 61). Soprattutto perché, sulla mia piattaforma, il numero magico che ritorna è 65. Anche quel codice si auto-documenterà meglio.
Grumdrig,

Ho creato un minification ottimizzato (46 byte più piccolo) variante della vostra implementazione qui: stackoverflow.com/a/52412162
Waruyama

In bocca al lupo per il debug di @Waruyama. Ecco a cosa serve il webpack!
Dylan Watson,

61

Generatore di stringhe casuali (alfanumerico | alfa | numerico)

/**
 * Pseudo-random string generator
 * http://stackoverflow.com/a/27872144/383904
 * Default: return a random alpha-numeric string
 * 
 * @param {Integer} len Desired length
 * @param {String} an Optional (alphanumeric), "a" (alpha), "n" (numeric)
 * @return {String}
 */
function randomString(len, an) {
  an = an && an.toLowerCase();
  var str = "",
    i = 0,
    min = an == "a" ? 10 : 0,
    max = an == "n" ? 10 : 62;
  for (; i++ < len;) {
    var r = Math.random() * (max - min) + min << 0;
    str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
  }
  return str;
}

console.log(randomString(10));      // i.e: "4Z8iNQag9v"
console.log(randomString(10, "a")); // i.e: "aUkZuHNcWw"
console.log(randomString(10, "n")); // i.e: "9055739230"


Mentre quanto sopra utilizza controlli aggiuntivi per l' output A / N, A, N desiderato, analizziamo l'essenziale (solo alfanumerico) per una migliore comprensione:

  • Creare una funzione che accetta un argomento (lunghezza desiderata del risultato String casuale)
  • Crea una stringa vuota come var str = "";concatenare caratteri casuali
  • All'interno di un ciclo creare un randnumero indice compreso tra 0 e 61 (0..9 + A..Z + a..z = 62)
  • Crea una logica condizionale per regolare / correggererand (dato che è 0..61) incrementandola di un numero (vedi esempi sotto) per ottenere il CharCodenumero giusto e il carattere correlato.
  • All'interno del ciclo concatenare ad strunString.fromCharCode( incremented rand )

Immaginiamo gli intervalli della tabella dei caratteri ASCII :

_____0....9______A..........Z______a..........z___________  Character
     | 10 |      |    26    |      |    26    |             Tot = 62 characters
    48....57    65..........90    97..........122           CharCode ranges

Math.floor( Math.random * 62 )dà una gamma da 0..61(ciò di cui abbiamo bisogno).
Risolviamo il casuale per ottenere gli intervalli charCode corretti :

      |   rand   | charCode |  (0..61)rand += fix            = charCode ranges |
------+----------+----------+--------------------------------+-----------------+
0..9  |   0..9   |  48..57  |  rand += 48                    =     48..57      |
A..Z  |  10..35  |  65..90  |  rand += 55 /*  90-35 = 55 */  =     65..90      |
a..z  |  36..61  |  97..122 |  rand += 61 /* 122-61 = 61 */  =     97..122     |

La logica dell'operazione condizionale dalla tabella sopra:

   rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand +=  true  ? (  true   ? 55 else 61 ) else 48 ;

Dalla spiegazione sopra, ecco lo snippet alfanumerico risultante :

function randomString(len) {
  var str = "";                                // String result
  for (var i = 0; i < len; i++) {              // Loop `len` times
    var rand = Math.floor(Math.random() * 62); // random: 0..61
    var charCode = rand += rand > 9 ? (rand < 36 ? 55 : 61) : 48; // Get correct charCode
    str += String.fromCharCode(charCode);      // add Character to str
  }
  return str; // After all loops are done, return the concatenated string
}

console.log(randomString(10)); // i.e: "7GL9F0ne6t"

O se vuoi:

const randomString = (n, r='') => {
  while (n--) r += String.fromCharCode((r=Math.random()*62|0, r+=r>9?(r<36?55:61):48));
  return r;
};

console.log(randomString(10))


33

Il modo più semplice è:

(new Date%9e6).toString(36)

Questo genera stringhe casuali di 5 caratteri in base all'ora corrente. L'output di esempio è 4mtxjo 4mv90o4mwp1

Il problema è che se lo chiami due volte nello stesso secondo, genererà la stessa stringa.

Il modo più sicuro è:

(0|Math.random()*9e6).toString(36)

Questo genererà una stringa casuale di 4 o 5 caratteri, sempre diversa. L'output di esempio è come 30jzmo 1r591o4su1a

In entrambi i modi la prima parte genera un numero casuale. La .toString(36)parte ha lanciato il numero su una rappresentazione base36 (alfa-decimale).


Non sono sicuro di come questo risponda alla domanda; Questa è una domanda di 7 anni con già molte risposte valide. Se si sceglie di fornire una nuova risposta, è necessario prestare particolare attenzione per assicurarsi che la risposta sia ben spiegata e documentata.
Claies,

1
Se usi Date, perché non lo usi semplicemente come:(+new Date).toString(36)
seniorpreacher

Mi piace la tua soluzione di numeri casuali ma 9e6 offre solo 9 milioni di possibilità rispetto ai 60,4 milioni per 5 cifre (36 ^ 5) in modo da poterlo sostituire con (0|Math.random()*6.04e7).toString(36)per coprirlo.
Le Droid,

1
Volevo una stringa casuale longish con una routine il più breve possibile (per una demo del codice) che non ha bisogno di essere crittograficamente sorprendente, produce solo un bel "fluff" visivo casuale. Mi piace questa risposta al meglio (la tua seconda), quindi grazie. I miei due centesimi: posso battere per brevità con una battitura di meno, ed in genere la produzione di 13 caratteri casuali (senza periodo): (Math.random()*1e20).toString(36).
Andrew Willems,

un problema che ho con questa risposta è che non utilizzerà [AZ] che si trova nella domanda originale.
user.friendly

22

Ecco alcune semplici linee. Cambia new Array(5)per impostare la lunghezza.

Compreso 0-9a-z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36);})

Compreso 0-9a-zA-Z

new Array(5).join().replace(/(.|$)/g, function(){return ((Math.random()*36)|0).toString(36)[Math.random()<.5?"toString":"toUpperCase"]();});

20

So che tutti hanno già capito bene, ma mi è sembrato di provarlo nel modo più leggero possibile (codice leggero, non CPU):

function rand(length, current) {
  current = current ? current : '';
  return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current;
}

console.log(rand(5));

Ci vuole un po 'di tempo per avvolgere la testa, ma penso che mostri davvero quanto sia fantastica la sintassi di JavaScript.


20
Se stai cercando di mantenere il codice breve, perché scrivere current = current ? current : '';quando puoi scrivere current = current || '';
CaffGeek,

9
dal momento che stiamo parlando di micro ottimizzazione qui in realtà suggerirei di saltare completamente l'assegnazione variabile se non necessario:current || (current = '');
Thomas Heymann

Tentare l'ottimizzazione micro mentre si utilizza un algoritmo ricorsivo "bello" ma non ha senso sprecare risorse :-) Un ciclo for è ancora il migliore in Javascript e batte la ricorsione alla grande, fino a quando non si realizzano grandi progressi nell'ottimizzazione del codice dei runtime.
Mörre,

17

Se stai usando Lodash o Underscore , è così semplice:

var randomVal = _.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 5).join('');

6
Lodash usa_.sampleSize('asdfgh',5).join('')
marlo il

2
Questa in realtà non è una buona soluzione, perché per ogni documento ogni personaggio proviene da un indice univoco. Ciò significa che non è veramente casuale, dal momento che nessun personaggio può / sarà mai ripetere.
random_user_name

16

Per soddisfare il requisito [a-zA-Z0-9] e lunghezza = 5 utilizzare

btoa(Math.random()).substr(5, 5);

Verranno visualizzate lettere minuscole, lettere maiuscole e numeri.


1
Immagino, Math.random () potrebbe portare a una stringa base64 con troppi caratteri.
Leif,

14

Nel caso in cui qualcuno sia interessato a un one-liner (anche se non formattato come tale per comodità) che alloca la memoria in una sola volta (ma nota che per le stringhe di piccole dimensioni non importa davvero) ecco come farlo:

Array.apply(0, Array(5)).map(function() {
    return (function(charset){
        return charset.charAt(Math.floor(Math.random() * charset.length))
    }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')

Puoi sostituirlo 5con la lunghezza della stringa che desideri. Grazie a @AriyaHidayat in questo post per la soluzione alla mapfunzione che non funziona sull'array sparse creato da Array(5).


13
Ogni programma javascript è un "one-liner" se lo formatti come tale
hacklikecrack,

13

Ecco il metodo che ho creato.
Creerà una stringa contenente caratteri sia maiuscoli che minuscoli.
Inoltre ho incluso la funzione che creerà anche una stringa alfanumerica.

Esempi di lavoro:
http://jsfiddle.net/greatbigmassive/vhsxs/ (solo alfa)
http://jsfiddle.net/greatbigmassive/PJwg8/ (alfanumerico)

function randString(x){
    var s = "";
    while(s.length<x&&x>0){
        var r = Math.random();
        s+= String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65));
    }
    return s;
}

Aggiornamento luglio 2015
Fa la stessa cosa ma ha più senso e include tutte le lettere.

var s = "";
while(s.length<x&&x>0){
    v = Math.random()<0.5?32:0;
    s += String.fromCharCode(Math.round(Math.random()*((122-v)-(97-v))+(97-v)));
}

Con questa funzione, non è mai possibile ottenere una lettera maiuscola maggiore di 'M' o una lettera minuscola minore di 'n'.
erkanyildiz,

Veramente? ooh! probabilmente lo proverò più allora. Hmm, tuttavia, dato che è una stringa casuale e non ci interessa davvero quali lettere ci siano (purché siano casuali), allora fa ancora quello che vogliamo che faccia tutto ciò che conta, ma sì, fornirà un aggiornamento, grazie.
Adam,

12

Supponendo che tu usi underscorejs è possibile generare elegantemente una stringa casuale in sole due righe:

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');

6
Ciò renderà il valore restituito con tutti i caratteri univoci. Inoltre, la lunghezza della stringa è limitata alla lunghezza di var possibile.
Yefu,

10
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

Soluzione semplice e pulita
Mark Swardstrom il

Questo merita un +1 più grande
Walid Ammar il

10

Algoritmo veloce e migliorato. Non garantisce l'uniforme (vedi commenti).

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    let result = '';

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}

2
Ottima risposta, ma la probabilità non è uniforme. Esistono 62 caratteri possibili e crypto.getRandomValuesrestituisce uno dei 256 valori univoci. Poiché 256 non è diviso per 62, si ottiene una probabilità leggermente maggiore di ottenere personaggi AH. Penso che la soluzione migliore sia fare quello che ha fatto YouTube e aggiungere semplicemente 2 caratteri aggiuntivi (possibilmente -e _) al set di caratteri. Comunque, ottimo lavoro - questa risposta richiede molto più amore :)
TeWu

aggiungendo - e _ è una grande idea poiché ti fornirà il set base64 completo url-sicuro
cowbert

8

Il problema con le risposte alle domande "Ho bisogno di stringhe casuali" (in qualsiasi lingua) è praticamente ogni soluzione utilizza una specifica primaria imperfetta della lunghezza della stringa . Le domande stesse raramente rivelano il motivo per cui sono necessarie stringhe casuali, ma sfiderei che raramente hai bisogno di stringhe casuali di lunghezza, diciamo 8. Ciò di cui hai inevitabilmente bisogno è un numero di stringhe uniche , ad esempio, da usare come identificatori per qualche scopo.

Esistono due modi principali per ottenere stringhe rigorosamente uniche : deterministicamente (che non è casuale) e store / compare (che è oneroso). Cosa facciamo? Rinunciamo al fantasma. Andiamo invece con unicità probabilistica . Cioè, accettiamo che ci sia qualche (anche se piccolo) rischio che le nostre stringhe non siano uniche. È qui che sono utili la comprensione della probabilità di collisione e dell'entropia .

Quindi riformulerò il bisogno invariabile in quanto necessitano di un numero di stringhe con un piccolo rischio di ripetizione. Ad esempio, supponiamo che tu voglia generare un potenziale di 5 milioni di ID. Non vuoi archiviare e confrontare ogni nuova stringa e vuoi che siano casuali, quindi accetti qualche rischio di ripetizione. Ad esempio, diciamo un rischio inferiore a 1 in una trilione di possibilità di ripetizione. Quindi di quale lunghezza hai bisogno? Bene, questa domanda è sottostimata in quanto dipende dai personaggi usati. Ma soprattutto, è fuorviato. Ciò di cui hai bisogno è una specifica dell'entropia delle stringhe, non della loro lunghezza. L'entropia può essere direttamente correlata alla probabilità di una ripetizione in un certo numero di stringhe. La lunghezza della stringa non può.

Ed è qui che può aiutare una libreria come EntropyString . Per generare ID casuali che hanno meno di 1 in trilioni di possibilità di ripetizione in 5 milioni di stringhe usando entropy-string:

import {Random, Entropy} from 'entropy-string'

const random = new Random()
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-stringutilizza un set di caratteri con 32 caratteri per impostazione predefinita. Esistono altri set di caratteri predefiniti e puoi anche specificare i tuoi personaggi. Ad esempio, generare ID con la stessa entropia di cui sopra ma utilizzando caratteri esadecimali:

import {Random, Entropy, charSet16} from './entropy-string'

const random = new Random(charSet16)
const bits = Entropy.bits(5e6, 1e12)

const string = random.string(bits)

"27b33372ade513715481f"

Notare la differenza nella lunghezza della stringa dovuta alla differenza nel numero totale di caratteri nel set di caratteri utilizzato. Il rischio di ripetizione nel numero specificato di stringhe potenziali è lo stesso. Le lunghezze delle stringhe non lo sono. E soprattutto, il rischio di ripetizione e il potenziale numero di stringhe sono espliciti. Non dovrai più indovinare con la lunghezza della stringa.


7
function randomString (strLength, charSet) {
    var result = [];

    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    while (--strLength) {
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }

    return result.join('');
}

Questo è pulito come sarà. È anche veloce, http://jsperf.com/ay-random-string .


Per me questo genera sempre stringhe casuali con strLength - 1: - /
xanderiel

3
Passare da --strLengtha strLength--risolverlo per me.
Xanderiel,

7

È possibile eseguire il ciclo tra una serie di elementi e aggiungerli in modo ricorsivo a una variabile stringa, ad esempio se si desidera una sequenza casuale di DNA:

function randomDNA(len) {
  len = len || 100
  var nuc = new Array("A", "T", "C", "G")
  var i = 0
  var n = 0
  s = ''
  while (i <= len - 1) {
    n = Math.floor(Math.random() * 4)
    s += nuc[n]
    i++
  }
  return s
}

console.log(randomDNA(5));


6

Non ho trovato una soluzione pulita per supportare sia i caratteri minuscoli che maiuscoli.

Supporto solo in minuscolo:

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

Basandosi su quella soluzione per supportare lettere minuscole e maiuscole:

Math.random().toString(36).substr(2, 5).split('').map(c => Math.random() < 0.5 ? c.toUpperCase() : c).join('');

Cambia 5in substr(2, 5)per regolare la lunghezza che ti serve.


6

Una fodera:

Array(15).fill(null).map(() => Math.random().toString(36).substr(2)).join('')
// Outputs: 0h61cbpw96y83qtnunwme5lxk1i70a6o5r5lckfcyh1dl9fffydcfxddd69ada9tu9jvqdx864xj1ul3wtfztmh2oz2vs3mv6ej0fe58ho1cftkjcuyl2lfkmxlwua83ibotxqc4guyuvrvtf60naob26t6swzpil

Per renderlo più breve, cambiare l'argomento in Array(15)un valore più piccolo. Ad esempio: Array(4).
Andrew

Adoro davvero questa soluzione, semplice e chiara. Sta generando 15 numeri casuali tra 0 e 1, genera l'esadecimale e quindi rimuove i primi due caratteri. Alla fine li sta unendo tutti insieme.
Siscia,

5

Questo funziona di sicuro

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>

5

Che ne dici di qualcosa del genere: Date.now().toString(36) non molto casuale, ma breve e piuttosto unico ogni volta che lo chiami.


1
Purtroppo questo non sarà unico, poiché Date.now()ha solo una risoluzione di millisecondi. Se eseguito in un semplice ciclo, ad esempio, otterrai molti duplicati. for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); }.
Nate,

5

Caratteri alfanumerici insensibili alle maiuscole:

function randStr(len) {
  let s = '';
  while (s.length < len) s += Math.random().toString(36).substr(2, len - s.length);
  return s;
}

// usage
console.log(randStr(50));

Il vantaggio di questa funzione è che puoi ottenere una stringa casuale di diversa lunghezza e garantisce la lunghezza della stringa.

Tutti i caratteri sensibili al maiuscolo / minuscolo:

function randStr(len) {
  let s = '';
  while (len--) s += String.fromCodePoint(Math.floor(Math.random() * (126 - 33) + 33));
  return s;
}

// usage
console.log(randStr(50));

Caratteri personalizzati

function randStr(len, chars='abc123') {
  let s = '';
  while (len--) s += chars[Math.floor(Math.random() * chars.length)];
  return s;
}

// usage
console.log(randStr(50));
console.log(randStr(50, 'abc'));
console.log(randStr(50, 'aab')); // more a than b


Questa risposta è più adatta al mio caso d'uso. Sarebbe bello se si potesse aggiungere un var possiblelike nella risposta accettata, quindi il risultato della funzione è più configurabile.
Denis.Sabolotni,

4

Genera una stringa lunga di 10 caratteri. La lunghezza è impostata dal parametro (valore predefinito 10).

function random_string_generator(len) {
var len = len || 10;
var str = '';
var i = 0;

for(i=0; i<len; i++) {
    switch(Math.floor(Math.random()*3+1)) {
        case 1: // digit
            str += (Math.floor(Math.random()*9)).toString();
        break;

        case 2: // small letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 97); //'a'.charCodeAt(0));
        break;

        case 3: // big letter
            str += String.fromCharCode(Math.floor(Math.random()*26) + 65); //'A'.charCodeAt(0));
        break;

        default:
        break;
    }
}
return str;
}

4

Puoi usare coderain . È una libreria per generare codici casuali secondo uno schema dato. Utilizzare #come segnaposto per caratteri maiuscoli e minuscoli e cifre:

var cr = new CodeRain("#####");
console.log(cr.next());

Esistono altri segnaposto come Alettere maiuscole o 9cifre.

Ciò che può essere utile è che chiamare .next()ti darà sempre un risultato unico, così non dovrai preoccuparti dei duplicati.

Ecco un'applicazione demo che genera un elenco di codici casuali univoci .

Divulgazione completa: sono l'autore di Coderain.


NO NO NO - usa metodi nativi.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.