javascript - Generera en sträng med slumpmässiga tecken


Jag vill ha en sträng med fast längd, sammansatt av tecken som slumpmässigt väljs från en uppsättning tecken t.ex. [a-zA-Z0-9].

Hur kan jag göra detta med JavaScript?

Svar #1

Jag tror att detta kommer att fungera för dig:

function makeid(length) {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const charactersLength = characters.length;
    let counter = 0;
    while (counter < length) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
      counter += 1;
    }
    return result;
}

console.log(makeid(5));

Svar #2

//Can change 7 to 2 for longer results.
let r = (Math.random() + 1).toString(36).substring(7);
console.log("random", r);

Observera: Ovanstående algoritm har följande svagheter:

  • Det kommer att generera mellan 0 och 6 tecken på grund av att avslutande nollor tas bort när flyttal omvandlas till strängar.
  • Det beror starkt på algoritmen som används för att göra flyttal till strängar, vilket är fruktansvärt komplext. (Se artikeln "How to Print Floating-Point Numbers Accurately".)
  • Math.random() kan ge förutsägbar ("slumpmässigt seende" men egentligen inte slumpmässig) output beroende på implementeringen. Den resulterande strängen är inte lämplig när du behöver garantera unikhet eller oförutsägbarhet.
  • Även om det producerade 6 helt slumpmässiga, oförutsägbara tecken, kan du förvänta dig att se en dubblett efter att ha genererat bara cirka 50 000 strängar, på grund av födelsedagsparadoxen. (sqrt(36^6)=46656)

Svar #3

Math.random är dåligt för den här typen av saker

serversida (node, bun)

Använd Node crypto-modul -

esm -

import * as crypto from "node:crypto";
const id = crypto.randomBytes(20).toString('hex');

console.log(id)
// "bb5dc8842ca31d4603d6aa11448d1654"

eller cjs -

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

console.log(id)
// "bb5dc8842ca31d4603d6aa11448d1654"

Den resulterande strängen kommer att vara dubbelt så lång som de slumpmässiga byte du genererar; varje byte kodad till hex är 2 tecken. 20 byte kommer att bli 40 tecken av hex.


klientsidan (webbläsare)

Använd webbläsarens kryptomodul -

const id = window.crypto.randomUUID()
console.log(id)
// bd4d099b-3d39-4aad-a59c-c45dfac8eaf0

Eller crypto.getRandomValues -

Metoden crypto.getRandomValues() låter dig få kryptografiskt starka slumpvärden. Arrayen som ges som parameter fylls med slumpmässiga nummer (slumpmässiga i dess kryptografiska betydelse).

// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
function dec2hex (dec) {
  return dec.toString(16).padStart(2, "0")
}

// 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"

Ett steg-för-steg-konsolexempel -

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

För IE11-stöd kan du använda -

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

För webbläsartäckning se https://caniuse.com/#feat=getrandomvalues


klientsidan (gamla webbläsare)

Om du måste stödja gamla webbläsare, överväg något som uuid -

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

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

Svar #4

Kort, lätt och pålitlig

Returnerar exakt 5 slumpmässiga tecken, till skillnad från några av de högst betygsatta svaren som finns här.

Math.random().toString(36).slice(2, 7);

Svar #5

Här är en förbättring av doubletaps utmärkta svar. Originalet har två nackdelar som åtgärdas här:

Först, som andra har nämnt, har det en liten sannolikhet att producera korta strängar eller till och med en tom sträng (om slumpnumret är 0), vilket kan bryta din applikation. Här är en lösning:

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

För det andra begränsar både originalet och lösningen ovan strängstorleken N till 16 tecken. Följande kommer att returnera en sträng av storlek N för vilket N som helst (men observera att användning av N > 16 inte kommer att öka slumpmässigheten eller minska sannolikheten för kollisioner):

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

Förklaring:

  1. Välj ett slumpmässigt tal i intervallet [0,1), det vill säga mellan 0 (inklusive) och 1 (exklusive).
  2. Konvertera numret till en bas-36-sträng, dvs. med tecken 0-9 och a-z.
  3. Fyll på med nollor (löser det första problemet).
  4. Skär av den ledande '0.'-prefixen och extra fyllnadsnollor.
  5. Upprepa strängen tillräckligt många gånger för att ha minst N tecken i den (genom att sammanfoga tomma strängar med den kortare slumpmässiga strängen som avgränsare).
  6. Skär exakt N tecken från strängen.

Ytterligare tankar:

  • Denna lösning använder inte versaler, men i nästan alla fall (ingen ordlek avsedd) spelar det ingen roll.
  • Maximala stränglängden vid N=16 i det ursprungliga svaret är mäts i Chrome. I Firefox är det N=11. Men som förklarats handlar den andra lösningen om att stödja vilken begärd stränglängd som helst, inte om att lägga till slumpmässighet, så det gör ingen större skillnad.
  • Alla returnerade strängar har en lika stor sannolikhet att returneras, åtminstone så långt resultaten som returneras av Math.random() är jämnt fördelade (detta är i alla fall inte slumpmässighet med kryptografisk styrka).
  • Alla möjliga strängar av storlek N kanske inte returneras. I den andra lösningen är detta uppenbart (eftersom den mindre strängen helt enkelt dupliceras), men även i det ursprungliga svaret är detta sant eftersom vid omvandlingen till bas-36 kanske de sista bitarna inte är en del av de ursprungliga slumpmässiga bitarna. Om du tittar på resultatet av Math.random().toString(36) kommer du specifikt att märka att den sista tecknet inte är jämnt fördelad. Återigen, i nästan alla fall spelar det ingen roll, men vi skär den slutliga strängen från början istället för slutet av den slumpmässiga strängen så att korta strängar (t.ex. N=1) inte påverkas.

Uppdatering:

Här är ett par andra funktionsstiliga enradare som jag kom på. De skiljer sig från lösningen ovan på det sätt att:

  • De använder ett explicit godtyckligt alfabet (mer generiskt och lämpligt för den ursprungliga frågan som efterfrågade både versaler och gemener).
  • Alla strängar av längd N har lika stor sannolikhet att returneras (dvs. strängarna innehåller inga upprepningar).
  • De är baserade på en kartfunktion, snarare än toString(36)-tricket, vilket gör dem mer okomplicerade och lätta att förstå.

Så, säg att ditt val av alfabet är

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Då är dessa två ekvivalenta med varandra, så du kan välja vilken som är mest intuitiv för dig:

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

och

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

Redigera:

Det verkar som att qubyte och Martijn de Milliano kom fram till lösningar som liknar den senare (bra gjort!), vilket jag på något sätt missade. Eftersom de inte ser lika korta ut vid en första anblick, lämnar jag det ändå här ifall någon verkligen vill ha en enradare :-)

Dessutom ersatte jag 'new Array' med 'Array' i alla lösningar för att spara några fler byte.

Svar #6

Den mest kompakta lösningen, eftersom slice är kortare än substring. Att subtrahera från slutet av strängen gör det möjligt att undvika flyttalssymboler som genereras av random-funktionen:

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

eller till och med

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

Uppdatering: Lagt till ett till angreppssätt med btoa-metoden:

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

Svar #7

En nyare version med es6 spridningsoperator:

[...Array(30)].map(() => Math.random().toString(36)[2]).join('')
  • Siffran 30 är ett godtyckligt nummer, du kan välja vilken tokenlängd du vill
  • 36 är det högsta basnumret du kan skicka till numeric.toString(), vilket betyder alla siffror och a-z små bokstäver
  • 2 används för att välja det tredje indexet från den slumpmässiga strängen som ser ut så här: "0.mfbiohx64i", vi kan ta vilket index som helst efter 0.

Svar #8

Något liknande detta bör fungera

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

Anropa med standardteckenuppsättning [a-zA-Z0-9] eller skicka in din egen:

var randomValue = randomString(5);

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

Svar #9

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

Svar #10

För att uppfylla kravet [a-zA-Z0-9] och längden på 5 tecken, använd

För webbläsare:

btoa(Math.random().toString()).substring(10,15);

För NodeJS:

Buffer.from(Math.random().toString()).toString("base64").substring(10,15);

Gemener, versaler och siffror kommer att förekomma.

(det är kompatibelt med TypeScript)

Svar #11

Slumpmässig stränggenerator (Alfanumerisk | Alfabetisk | Numerisk)

/**
 * 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"

Medan ovanstående använder ytterligare kontroller för önskat A/N, A, N-utdata, låt oss bryta ner det till det mest grundläggande (endast alfanumeriskt) för en bättre förståelse:

  • Skapa en funktion som accepterar ett argument (önskad längd på det slumpmässiga strängresultatet)
  • Skapa en tom sträng som var str=""; för att sammanfoga slumpmässiga tecken
  • Inuti en loop skapa ett rand indexnummer från 0 till 61 (0..9+A..Z+a..z=62)
  • Skapa en villkorslogik för att justera/fixa rand (eftersom det är 0..61) genom att öka det med ett visst nummer (se exempel nedan) för att få tillbaka rätt CharCode-nummer och den relaterade tecken.
  • Inuti loopen sammanfoga till str en String.fromCharCode( incremented rand )

Låt oss föreställa oss ASCII-teckentabellens intervall:

_____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 ) ger ett område från 0..61 (precis vad vi behöver).
Låt oss fixa slumpen för att få korrekt charCode-intervall:

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

Villkorsstyrd operationslogik från tabellen ovan:

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

Från förklaringen ovan, här är den resulterande alfanumeriska koden:

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"

Eller om du vill:

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

Svar #12

Det enklaste sättet är:

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

Detta genererar slumpmässiga strängar på 5 tecken baserat på den aktuella tiden. Exempel på utdata är 4mtxj eller 4mv90 eller 4mwp1

Problemet med detta är att om du kallar det två gånger på samma sekund, kommer det att generera samma sträng.

Det säkrare sättet är:

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

Detta kommer att generera en slumpmässig sträng på 4 eller 5 tecken, alltid olika. Exempel på utskrift är som 30jzm eller 1r591 eller 4su1a

I båda fallen genererar den första delen ett slumpmässigt nummer. Delen .toString(36) omvandlar numret till en bas36 (alfanumerisk) representation av det.

Svar #13

Här är några enkla enradare. Ändra new Array(5) för att sätta längden.

Inklusive 0-9a-z

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

Inklusive 0-9a-zA-Z

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

Codegolfad för ES6 (0-9a-z)

Array(5).fill().map(n=>(Math.random()*36|0).toString(36)).join('')

Svar #14

Det finns inget bästa sätt att göra detta. Du kan göra det på vilket sätt du föredrar, så länge resultatet passar dina krav. För att illustrera har jag skapat många olika exempel, som alla borde ge samma slutresultat

De flesta andra svar på den här sidan ignorerar kravet på versaler.

Här är min snabbaste lösning och mest lättlästa. Den gör i princip samma sak som den accepterade lösningen, förutom att den är lite snabbare.

function readableRandomStringMaker(length) {
  for (var s=''; s.length < length; s += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.charAt(Math.random()*62|0));
  return s;
}
console.log(readableRandomStringMaker(length));
// e3cbN

Här är en kompakt, rekursiv version som är mycket mindre läsbar:

const compactRandomStringMaker = (length) => length-- && "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) + (compactRandomStringMaker(length)||"");
console.log(compactRandomStringMaker(5));
// DVudj

En mer kompakt enradare:

Array(5).fill().map(()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62)).join("")
// 12oEZ

En variation av det ovanstående:

"     ".replaceAll(" ",()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62))

Den mest kompakta enradaren, men ineffektiv och oläslig - den lägger till slumpmässiga tecken och tar bort olagliga tecken tills längden är l:

((l,f=(p='')=>p.length<l?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())(5)

En kryptografiskt säker version, som slösar med entropi för kompakthet, och är ändå ett slöseri eftersom den genererade strängen är så kort:

[...crypto.getRandomValues(new Uint8Array(999))].map((c)=>String.fromCharCode(c).replace(/[^a-z0-9]/i,'')).join("").substr(0,5)
// 8fzPq

Eller, utan längd-argumentet är det ännu kortare:

((f=(p='')=>p.length<5?f(p+String.fromCharCode(Math.random()*123).replace(/[^a-z0-9]/i,'')):p)=>f())()
// EV6c9

Sedan lite mer utmanande - med en namnlös rekursiv pilfunktion:

((l,s=((l)=>l--&&"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0)+(s(l)||""))) => s(l))(5);
// qzal4

Detta är en "magisk" variabel som ger en slumpmässig tecken varje gång du använder den:

const c = new class { [Symbol.toPrimitive]() { return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0) } };
console.log(c+c+c+c+c);
// AgMnz

En enklare variant av ovanstående:

const c=()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0);
c()+c()+c()+c()+c();
// 6Qadw

Svar #15

Jag vet att alla redan har fått det rätt, men jag kände för att ge mig på den här på det mest lättviktiga sättet möjligt (lätt på kod, inte 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));

Det tar lite tid att förstå, men jag tycker verkligen att det visar hur fantastisk javascripts syntax är.

Svar #16

Generera en säker slumpmässig alfanumerisk Base-62-sträng:

function generateUID(length)
{
    return window.btoa(String.fromCharCode(...window.crypto.getRandomValues(new Uint8Array(length * 2)))).replace(/[+/]/g, "").substring(0, length);
}

console.log(generateUID(22)); // "yFg3Upv2cE9cKOXd7hHwWp"
console.log(generateUID(5)); // "YQGzP"

Svar #17

Även om detta svar nästan är likt andra, skiljer det sig åt genom att det använder:

  • repeat för att skapa 5 tecken (kan generaliseras till n)
  • replace med regex /./g för att ersätta de där 5 tecknen
  • formeln är att slumpmässigt välja en karaktär från en 62 tecken lång A-Za-z0-9 sträng

let ans = "x".repeat(5)
             .replace(/./g, c => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[Math.floor(Math.random() * 62) ] );
console.log(ans);

Svar #18

Om någon är intresserad av en enradare (även om den inte är formaterad så för din bekvämlighet) som allokerar minnet på en gång (men observera att det verkligen inte spelar någon roll för små strängar) här är hur man gör det:

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

Du kan ersätta 5 med längden på den sträng du vill ha. Tack till @AriyaHidayat i detta inlägg för lösningen på att map-funktionen inte fungerar på den glest befolkade array som skapats av Array(5).

Svar #19

Om du använder Lodash eller Underscore:

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

Svar #20

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

Svar #21

Här är metoden jag skapade.
Den kommer att skapa en sträng som innehåller både versaler och gemener.
Dessutom har jag inkluderat funktionen som också kommer att skapa en alfanumerisk sträng.

Arbetande exempel:
http://jsfiddle.net/greatbigmassive/vhsxs/ (endast alfabet)
http://jsfiddle.net/greatbigmassive/PJwg8/ (alfanumerisk)

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

Uppgradering juli 2015
Detta gör samma sak men är mer logiskt och inkluderar alla bokstäver.

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

Svar #22

Enradare:

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

Svar #23

Förbättrad @Andrews svar ovan:

Array.from({ length : 1 }, () => Math.random().toString(36)[2]).join('');

Bas 36-omvandlingen av det slumpmässiga numret är inkonsekvent, så att välja ett enda index löser det. Du kan ändra längden för en sträng med exakt önskad längd.

Svar #24

Om du antar att du använder underscorejs är det möjligt att elegant generera en slumpmässig sträng på bara två rader:

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

Svar #25

function randomString (strLength, charSet) {
    var result = [];
    
    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    
    while (strLength--) { // (note, fixed typo)
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }
    
    return result.join('');
}

Det här är så rent det blir. Det är snabbt också, http://jsperf.com/ay-random-string.

Svar #26

Generera en slumpmässig sträng på 5 tecken [a-zA-Z0-9] på en rad:

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

Svar #27

Snabb och förbättrad algoritm. Ger ingen garanti för enhetlig (se kommentarer).

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

Svar #28

Vad sägs om detta kompakta lilla knep?

var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var stringLength = 5;

function pickRandom() {
    return possible[Math.floor(Math.random() * possible.length)];
}

var randomString = Array.apply(null, Array(stringLength)).map(pickRandom).join('');

Du behöver Array.apply där för att lura den tomma arrayen att bli en array av undefineds.

Om du programmerar för ES2015 är det lite enklare att bygga arrayen:

var randomString = Array.from({ length: stringLength }, pickRandom).join('');

Svar #29

Du kan loopa igenom en array av objekt och rekursivt lägga till dem i en strängvariabel, till exempel om du ville ha en slumpmässig DNA-sekvens:

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

Svar #30

Skiftlägesokänsliga alfanumeriska tecken:

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

Fördelen med denna funktion är att du kan få slumpmässiga strängar av olika längd och den säkerställer strängens längd.

Skiftlägeskänsliga alla tecken:

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

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

Anpassade tecken

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

Relaterade artiklar