簡體   English   中英

在 JavaScript 中生成隨機字符串/字符

[英]Generate random string/characters in JavaScript

我想要一個 5 個字符的字符串,由從集合[a-zA-Z0-9]中隨機挑選的字符組成。

使用 JavaScript 執行此操作的最佳方法是什么?

我認為這對你有用:

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

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

注意:上述算法有以下弱點:

  • 由於在對浮點進行字符串化時會刪除尾隨零,因此它將生成 0 到 6 個字符之間的任何字符。
  • 它在很大程度上取決於用於對浮點數進行字符串化的算法,這非常復雜。 (請參閱論文“如何准確打印浮點數” 。)
  • Math.random()可能會根據實現產生可預測的(“隨機的”但不是真正隨機的)輸出。 當您需要保證唯一性或不可預測性時,生成的字符串不適合。
  • 即使它生成了 6 個均勻隨機的、不可預測的字符,由於生日悖論,您可能會在僅生成大約 50,000 個字符串后看到重復的字符。 (sqrt(36^6) = 46656)

Math.random對這種事情不利

選項1

如果你能夠做這個服務器端,只需使用加密模塊 -

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

// "bb5dc8842ca31d4603d6aa11448d1654"

結果字符串將是您生成的隨機字節的兩倍; 編碼為十六進制的每個字節是 2 個字符。 20 個字節將是 40 個十六進制字符。


選項 2

如果你必須做這個客戶端,也許試試 uuid 模塊 -

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

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

選項 3

如果你必須做這個客戶端並且你不必支持舊的瀏覽器,你可以在沒有依賴關系的情況下做到這一點 -

 // dec2hex :: Integer -> String // ie 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"


有關crypto.getRandomValues的更多信息 -

crypto.getRandomValues()方法可讓您獲得加密的強隨機值。 作為參數給出的數組填充了隨機數(在其密碼學意義上是隨機的)。

這是一個小控制台示例 -

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

對於 IE11 支持,您可以使用 -

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

有關瀏覽器覆蓋率,請參閱https://caniuse.com/#feat=getrandomvalues

簡短、簡單、可靠

正好返回 5 個隨機字符,而不是此處找到的一些評分最高的答案。

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

這是對doubletap 的出色答案的改進。 原版有兩個缺點,這里要解決:

首先,正如其他人所提到的,它產生短字符串甚至是空字符串(如果隨機數為0)的可能性很小,這可能會破壞您的應用程序。 這是一個解決方案:

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

其次,原始和上述解決方案都將字符串大小 N 限制為 16 個字符。 以下將為任何 N 返回一個大小為 N 的字符串(但請注意,使用 N > 16 不會增加隨機性或降低碰撞概率):

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

解釋:

  1. 在 [0,1) 范圍內選擇一個隨機數,即介於 0(包括)和 1(不包括)之間。
  2. 將數字轉換為 base-36 字符串,即使用字符 0-9 和 az。
  3. 用零填充(解決第一個問題)。
  4. 切掉前面的“0”。 前綴和額外的填充零。
  5. 將字符串重復足夠多的時間以使其中至少包含 N 個字符(通過將空字符串與用作分隔符的較短隨機字符串連接起來)。
  6. 從字符串中精確切出 N 個字符。

進一步的想法:

  • 此解決方案不使用大寫字母,但在幾乎所有情況下(沒有雙關語)都沒有關系。
  • 原始答案中 N = 16 處的最大字符串長度是在 Chrome 中測量的。 在 Firefox 中,它是 N = 11。但正如所解釋的,第二種解決方案是關於支持任何請求的字符串長度,而不是關於添加隨機性,所以它沒有太大的區別。
  • 所有返回的字符串都具有相同的返回概率,至少在 Math.random() 返回的結果是均勻分布的范圍內(無論如何,這不是加密強度的隨機性)。
  • 並非所有可能的大小為 N 的字符串都可以返回。 在第二種解決方案中,這很明顯(因為只是復制了較小的字符串),但在原始答案中也是如此,因為在轉換為 base-36 時,最后幾位可能不是原始隨機位的一部分。 具體來說,如果您查看 Math.random().toString(36) 的結果,您會注意到最后一個字符不是均勻分布的。 同樣,幾乎在所有情況下都沒有關系,但是我們從隨機字符串的開頭而不是結尾對最終字符串進行切片,這樣短字符串(例如 N=1)就不會受到影響。

更新:

這是我想出的其他幾個函數式單行代碼。 它們與上述解決方案的不同之處在於:

  • 他們使用明確的任意字母(更通用,並且適合要求大寫和小寫字母的原始問題)。
  • 所有長度為 N 的字符串都具有相同的返回概率(即字符串不包含重復)。
  • 它們基於 map 函數,而不是 toString(36) 技巧,這使得它們更簡單易懂。

所以,假設你選擇的字母表是

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

那么這兩個是等價的,所以你可以選擇對你來說更直觀的一個:

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

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

編輯:

我似乎qubyteMartijn de Milliano提出了與后者類似的解決方案(贊!),我不知何故錯過了。 因為它們一目了然,所以我還是把它留在這里,以防有人真的想要單線:-)

此外,在所有解決方案中將 'new Array' 替換為 'Array' 以減少更多字節。

最緊湊的解決方案,因為slicesubstring短。 從字符串的末尾減去可以避免random函數生成的浮點符號:

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

甚至

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

更新:使用btoa方法添加了另一種方法:

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

帶有es6 擴展運算符的較新版本:

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

  • 30是一個任意數字,你可以選擇任何你想要的令牌長度
  • 36是您可以傳遞給numeric.toString()的最大基數,這意味着所有數字和 az 小寫字母
  • 2用於從如下所示的隨機字符串中選擇第三個索引: "0.mfbiohx64i" ,我們可以取0.

像這樣的東西應該工作

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

使用默認字符集 [a-zA-Z0-9] 調用或發送您自己的:

var randomValue = randomString(5);

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

 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); //AZ return String.fromCharCode(n + 61); //az } while (s.length < L) s += randomchar(); return s; } console.log(randomstring(5));

隨機字符串生成器(字母數字 | 字母 | 數字)

 /** * 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)); // ie: "4Z8iNQag9v" console.log(randomString(10, "a")); // ie: "aUkZuHNcWw" console.log(randomString(10, "n")); // ie: "9055739230"


雖然上面對所需的 A/N、A、N輸出使用了額外的檢查,但讓我們將其分解為基本要素(僅限字母數字)以便更好地理解:

  • 創建一個接受參數的函數(隨機字符串結果的所需長度)
  • 創建一個空字符串,如var str = ""; 連接隨機字符
  • 在循環內創建rand0 到 61 (0..9+A..Z+a..z = 62) 的 rand 索引號
  • 創建一個條件邏輯調整/修復rand (因為它是 0..61),將其增加一些數字(參見下面的示例)以取回正確的CharCode數字和相關的字符。
  • 在循環內連接到str a String.fromCharCode( incremented rand )

讓我們想象一下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 )給出的范圍是0..61 (我們需要的)。
讓我們修復隨機數以獲得正確的charCode 范圍

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

上表條件運算邏輯

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

根據上面的解釋,這是生成的字母數字片段

 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)); // ie: "7GL9F0ne6t"

或者,如果您願意:

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

為了滿足要求 [a-zA-Z0-9] 和 length=5 使用

對於瀏覽器

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

對於NodeJS

Buffer.from(Math.random().toString()).toString("base64").substr(10, 5);

會出現小寫字母、大寫字母和數字。

(它與打字稿兼容)

最簡單的方法是:

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

這會根據當前時間生成 5 個字符的隨機字符串。 示例輸出為4mtxj4mv904mwp1

這樣做的問題是,如果您在同一秒內調用它兩次,它將生成相同的字符串。

更安全的方法是:

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

這將生成一個 4 或 5 個字符的隨機字符串,總是不同的。 示例輸出類似於30jzm1r5914su1a

在這兩種方式中,第一部分都會生成一個隨機數。 .toString(36)部分將數字轉換為它的 base36(alphadecimal)表示。

這里有一些簡單的襯線。 更改new Array(5)以設置長度。

包括0-9a-z

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

包括0-9a-zA-Z

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

我知道每個人都已經做對了,但我想以最輕量級的方式嘗試這個(代碼,而不是 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));

這需要一些時間來理解,但我認為它確實顯示了 javascript 的語法是多么的棒。

生成一個安全的隨機字母數字Base-62字符串:

 function generateUID(length) { return window.btoa(Array.from(window.crypto.getRandomValues(new Uint8Array(length * 2))).map((b) => String.fromCharCode(b)).join("")).replace(/[+/]/g, "").substring(0, length); } console.log(generateUID(22)); // "yFg3Upv2cE9cKOXd7hHwWp" console.log(generateUID(5)); // "YQGzP"

如果有人對一次性分配內存(但請注意,對於小字符串真的無關緊要)的單線(盡管為了您的方便沒有格式化)感興趣,這里是如何做到的:

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

您可以將5替換為所需字符串的長度。 感謝這篇文章中的@AriyaHidayat 解決了map函數在Array(5)創建的稀疏數組上不起作用的解決方案。

如果你使用LodashUnderscore ,那么它就這么簡單:

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

沒有最好的方法來做到這一點。 只要結果符合您的要求,您就可以按照您喜歡的任何方式進行操作。 為了說明,我創建了許多不同的示例,所有這些示例都應該提供相同的最終結果

此頁面上的大多數其他答案都忽略了大寫字符的要求。

這是我最快的解決方案最易讀的。 它基本上與公認的解決方案相同,只是速度更快一些。

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

這是一個緊湊的遞歸版本,可讀性要差得多:

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

更緊湊的單線

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

上述變體:

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

最緊湊的單行代碼,但效率低且不可讀 - 它添加隨機字符並刪除非法字符,直到長度為l

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

一個加密安全的版本,為了緊湊而浪費熵,而且不管因為生成的字符串太短,都是一種浪費:

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

或者,沒有長度參數,它甚至更短:

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

然后更具挑戰性 - 使用無名遞歸箭頭函數

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

這是一個“魔法”變量,每次訪問它時都會提供一個隨機字符:

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

上面的一個更簡單的變體:

const c=()=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.random()*62|0);
c()+c()+c()+c()+c();
// 6Qadw
const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = [...Array(5)].map(_ => c[~~(Math.random()*c.length)]).join('')

這是我創建的方法。
它將創建一個包含大寫和小寫字符的字符串。
此外,我還包含了將創建一個字母數字字符串的函數。

工作示例:
http://jsfiddle.net/greatbigmassive/vhsxs/ (僅 alpha 版)
http://jsfiddle.net/greatbigmassive/PJwg8/ (字母數字)

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

2015 年 7 月升級
這做同樣的事情,但更有意義,包括所有字母。

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

改進了@Andrew 上面的回答:

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

隨機數的基數 36 轉換不一致,因此選擇單個索引可以解決該問題。 您可以將字符串的長度更改為所需的確切長度。

假設您使用underscorejs ,則可以僅用兩行優雅地生成隨機字符串:

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

一個班輪:

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

快速和改進的算法。 不保證統一(見評論)。

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

這是盡可能干凈的。 它也很快, http://jsperf.com/ay-random-string

這個緊湊的小技巧怎么樣?

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

您需要那里的Array.apply來欺騙空數組成為未定義數組。

如果您正在為 ES2015 編寫代碼,那么構建數組會更簡單一些:

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

不區分大小寫的字母數字字符:

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

這個函數的好處是可以得到不同長度的隨機字符串,並且保證了字符串的長度。

區分大小寫的所有字符:

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

自定義字符

 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

您可以遍歷一組項目並遞歸地將它們添加到字符串變量中,例如,如果您想要一個隨機 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));

回答“我需要隨機字符串”問題(無論使用何種語言)的問題實際上是每個解決方案都使用有缺陷的字符串長度主要規范。 這些問題本身很少揭示為什么需要隨機字符串,但我會挑戰你很少需要長度的隨機字符串,比如 8。你總是需要一些唯一的字符串,例如,用作某些目的的標識符。

有兩種主要的方法來獲取嚴格唯一的字符串:確定性(不是隨機的)和存儲/比較(這是繁重的)。 我們做什么? 我們放棄了幽靈。 相反,我們使用概率唯一性 也就是說,我們接受存在一些(盡管很小)我們的字符串不是唯一的風險。 這就是理解碰撞概率有幫助的地方。

因此,我將把不變的需求重新表述為需要一些重復風險很小的字符串。 舉個具體的例子,假設您想生成 500 萬個 ID 的潛力。 您不想存儲和比較每個新字符串,並且希望它們是隨機的,因此您接受一些重復的風險。 例如,假設重復的風險小於萬億分之一。 那么你需要多長的字符串呢? 好吧,這個問題沒有詳細說明,因為它取決於所使用的字符。 但更重要的是,它被誤導了。 您需要的是字符串熵的規范,而不是它們的長度。 熵可以直接與一些字符串中重復的概率相關。 字符串長度不能。

這就是像EntropyString這樣的庫可以提供幫助的地方。 使用entropy-string生成在 500 萬個字符串中重復概率小於萬億分之一的隨機 ID:

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

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

const string = random.string(bits)

“44hTNghjNHGGRHqH9”

entropy-string默認使用 32 個字符的字符集。 還有其他預定義的字符集,您也可以指定自己的字符。 例如,生成具有與上述相同熵但使用十六進制字符的 ID:

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

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

const string = random.string(bits)

“27b33372ade513715481f”

請注意由於使用的字符集中字符總數的不同而導致的字符串長度的差異。 在指定數量的潛在字符串中重復的風險是相同的。 字符串長度不是。 最重要的是,重復的風險和潛在的字符串數量是明確的。 不再猜測字符串長度。

加密強

如果您想獲得滿足您要求的加密強字符串(我看到使用此但給出無效答案的答案)使用

let pass = n=> [...crypto.getRandomValues(new Uint8Array(n))]
   .map((x,i)=>(i=x/255*61|0,String.fromCharCode(i+(i>9?i>35?61:55:48)))).join``

 let pass = n=> [...crypto.getRandomValues(new Uint8Array(n))] .map((x,i)=>(i=x/255*61|0,String.fromCharCode(i+(i>9?i>35?61:55:48)))).join`` console.log(pass(5));

更新:感謝Zibri評論,我更新了代碼以獲得任意長的密碼

我沒有找到支持小寫和大寫字符的干凈解決方案。

僅小寫支持:

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

在該解決方案的基礎上支持小寫和大寫:

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

更改substr(2, 5)中的5以調整到您需要的長度。

這是我的方法(使用 TypeScript)。

我決定再寫一個回復,因為我沒有看到任何使用現代 js 和干凈代碼的簡單解決方案。

const DEFAULT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

function getRandomCharFromAlphabet(alphabet: string): string {
  return alphabet.charAt(Math.floor(Math.random() * alphabet.length));
}

function generateId(idDesiredLength: number, alphabet = DEFAULT_ALPHABET): string {
  /**
   * Create n-long array and map it to random chars from given alphabet.
   * Then join individual chars as string
   */
  return Array.from({length: idDesiredLength}).map(() => {
    return getRandomCharFromAlphabet(alphabet);
  }).join('');
}

generateId(5); // jNVv7

使用地圖的單線,可讓您完全控制長度和字符。

const rnd = (len, chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') => [...Array(len)].map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join('')

console.log(rnd(12))

只需一個簡單的mapreduce實現就足夠了:

const charset: string =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

const random1: string = [...Array(5)]
  .map((_) => charset[Math.floor(Math.random() * charset.length)])
  .join("");

const random2: string = [...Array(5)]
  .reduce<string>(
    (acc) => acc += charset[Math.floor(Math.random() * charset.length)],
    "",
  );

生成 10 個字符的長字符串。 長度由參數設置(默認為 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;
}

這肯定有效

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

像這樣的東西怎么樣: Date.now().toString(36)不是很隨機,但每次調用它時都很短且非常獨特。

這是我用的。 這里是一對夫婦的組合。 我循環使用它,它產生的每個 ID 都是唯一的。 它可能不是 5 個字符,但保證是唯一的。

var newId =
    "randomid_" +
    (Math.random() / +new Date()).toString(36).replace(/[^a-z]+/g, '');

這是#1答案的測試腳本(謝謝@csharptest.net)

該腳本運行makeid() 1 million次,如您所見,5 並不是一個非常獨特的。 以 10 的字符長度運行它是非常可靠的。 我已經運行了大約 50 次,還沒有看到重復的:-)

注意:節點堆棧大小限制超過 400 萬左右,所以你不能運行這 500 萬次,它永遠不會完成。

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

ids ={}
count = 0
for (var i = 0; i < 1000000; i++) {
    tempId = makeid();
    if (typeof ids[tempId] !== 'undefined') {
        ids[tempId]++;
        if (ids[tempId] === 2) {
            count ++;
        }
        count++;
    }else{
        ids[tempId] = 1;
    }
}
console.log("there are "+count+ ' duplicate ids');

您可以使用coderain 它是一個根據給定模式生成隨機代碼的庫。 使用#作為大小寫字符以及數字的占位符:

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

還有其他占位符,例如A代表大寫字母或9代表數字。

可能有用的是調用.next()總是會給你一個獨特的結果,所以你不必擔心重復。

這是一個生成唯一隨機代碼列表的演示應用程序。

全面披露:我是 coderain 的作者。

這個結合了許多給出的答案。

 var randNo = Math.floor(Math.random() * 100) + 2 + "" + new Date().getTime() + Math.floor(Math.random() * 100) + 2 + (Math.random().toString(36).replace(/[^a-zA-Z]+/g, '').substr(0, 5)); console.log(randNo);

我已經使用它 1 個月了,效果很好。

一個班輪 [az]:

String.fromCharCode(97 + Math.floor(Math.random() * 26))

如果你在node js上開發,最好使用crypto。 下面是一個實現randomStr()函數的例子

const crypto = require('crypto');
const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(crypto.randomInt(charset.length)))
    .join('');

如果您不在服務器環境中工作,只需更換隨機數生成器:

const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnopqrstuvwxyz';
const randomStr = (length = 5) => new Array(length)
    .fill(null)
    .map(() => charset.charAt(Math.floor(Math.random() * charset.length)))
    .join('');

通過回答 Gertas 和 Dragon 提出的問題來擴展 Doubletap 的優雅示例。 只需添加一個 while 循環來測試那些罕見的空情況,並將字符限制為五個。

function rndStr() {
    x=Math.random().toString(36).substring(7).substr(0,5);
    while (x.length!=5){
        x=Math.random().toString(36).substring(7).substr(0,5);
    }
    return x;
}

這是一個 jsfiddle 警告您的結果:http: //jsfiddle.net/pLJJ7/

如果你只想要 AZ:

randomAZ(n: number): string {
      return Array(n)
        .fill(null)
        .map(() => Math.random()*100%25 + 'A'.charCodeAt(0))
        .map(a => String.fromCharCode(a))
        .join('')
 }
"12345".split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');

//or

String.prototype.rand = function() {return this.split('').map(function(){return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.charAt(Math.floor(62*Math.random()));}).join('');};

將生成一個隨機的字母數字字符串,其長度為第一個/調用字符串的長度

同樣基於 doubletap 的回答,這個可以處理任意長度的隨機所需字符(僅較低),並不斷生成隨機數,直到收集到足夠的字符。

function randomChars(len) {
    var chars = '';

    while (chars.length < len) {
        chars += Math.random().toString(36).substring(2);
    }

    // Remove unnecessary additional characters.
    return chars.substring(0, len);
}

如果可以使用庫,Chance.js 可能會有所幫助: http ://chancejs.com/#string

對於包含大小寫字母和數字 (0-9a-zA-Z) 的字符串,這可能是最好的縮小版本:

function makeId(length) {
  var id = '';
  var rdm62;
  while (length--) {
   // Generate random integer between 0 and 61, 0|x works for Math.floor(x) in this case 
   rdm62 = 0 | Math.random() * 62; 
   // Map to ascii codes: 0-9 to 48-57 (0-9), 10-35 to 65-90 (A-Z), 36-61 to 97-122 (a-z)
   id += String.fromCharCode(rdm62 + (rdm62 < 10 ? 48 : rdm62 < 36 ? 55 : 61)) 
  }
  return id;
}

這個函數的內容縮小到 97 個字節,而上面的答案需要 149 個字節(因為字符列表)。

這是doubletap答案的稍微改進的版本。 Math.random()返回 0、0.5、0.25、0.125 等時,它會考慮gertas對該案例的評論。

((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)
  1. 它可以防止零傳遞給toString我將最小的浮點數添加到Math.random()
  2. 它通過除以幾乎無理數來確保傳遞給toString的數字有足夠的位數。

下面這個怎么樣......這將產生真正的隨機值:

function getRandomStrings(length) {
  const value = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const randoms = [];
  for(let i=0; i < length; i++) {
     randoms.push(value[Math.floor(Math.random()*value.length)]);
  }
  return randoms.join('');
}

但是,如果您在ES6中尋找更短的語法:

const getRandomStrings = length => Math.random().toString(36).substr(-length);

生成任意數量的十六進制字符(例如 32):

(function(max){let r='';for(let i=0;i<max/13;i++)r+=(Math.random()+1).toString(16).substring(2);return r.substring(0,max).toUpperCase()})(32);

為后代發布一個與 ES6 兼容的版本。 如果這被調用了很多,請務必將 .length 值存儲到常量變量中。

// USAGE:
//      RandomString(5);
//      RandomString(5, 'all');
//      RandomString(5, 'characters', '0123456789');
const RandomString = (length, style = 'frictionless', characters = '') => {
    const Styles = {
        'all':          allCharacters,
        'frictionless': frictionless,
        'characters':   provided
    }

    let result              = '';
    const allCharacters     = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const frictionless      = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
    const provided          = characters;

    const generate = (set) => {
        return set.charAt(Math.floor(Math.random() * set.length));
    };

    for ( let i = 0; i < length; i++ ) {
        switch(Styles[style]) {
            case Styles.all:
                result += generate(allCharacters);
                break;
            case Styles.frictionless:
                result += generate(frictionless);
                break;
            case Styles.characters:
                result += generate(provided);
                break;
        }
    }
    return result;
}

export default RandomString;
",,,,,".replace(/,/g,function (){return "AzByC0xDwEv9FuGt8HsIrJ7qKpLo6MnNmO5lPkQj4RiShT3gUfVe2WdXcY1bZa".charAt(Math.floor(Math.random()*62))});

這將 5 個字母數字字符存儲在變量 c 中。

for(var c = ''; c.length < 5;) c += Math.random().toString(36).substr(2, 1)

我喜歡 doubletap 的 Math.random().toString(36).substring(7) 答案的簡潔性,但並不像 hacklikecrack 正確指出的那樣有這么多的沖突。 它生成了 11 個字符的字符串,但在 100 萬個樣本中的重復率為 11%。

這是一個更長(但仍然很短)和更慢的替代方案,在 100 萬個樣本空間中只有 133 個重復項。 在極少數情況下,字符串仍會短於 11 個字符:

Math.abs(Math.random().toString().split('')
    .reduce(function(p,c){return (p<<5)-p+c})).toString(36).substr(0,11);

這是用於 Firefox chrome 代碼(插件等)

它可以為您節省幾個小時的研究時間。

function randomBytes( amount )
{
    let bytes = Cc[ '@mozilla.org/security/random-generator;1' ]

        .getService         ( Ci.nsIRandomGenerator )
        .generateRandomBytes( amount, ''            )

    return bytes.reduce( bytes2Number )


    function bytes2Number( previousValue, currentValue, index, array )
    {
      return Math.pow( 256, index ) * currentValue + previousValue
    }
}

將其用作:

let   strlen   = 5
    , radix    = 36
    , filename = randomBytes( strlen ).toString( radix ).splice( - strlen )

將字符作為thisArg放在 map 函數中將創建一個“單線”:

Array.apply(null, Array(5))
.map(function(){ 
    return this[Math.floor(Math.random()*this.length)];
}, "abcdefghijklmnopqrstuvwxyz")
.join('');

一種功能性方法。 可以在應用程序的其他部分中利用功能先決條件時,此答案才實用。 表演可能是垃圾,但寫起來非常有趣。

 // functional prerequisites const U = f=> f (f) const Y = U (h=> f=> f (x=> h (h) (f) (x))) const comp = f=> g=> x=> f (g (x)) const foldk = Y (h=> f=> y=> ([x, ...xs])=> x === undefined ? y : f (y) (x) (y=> h (f) (y) (xs))) const fold = f=> foldk (y=> x=> k=> k (f (y) (x))) const map = f=> fold (y=> x=> [...y, f (x)]) ([]) const char = x=> String.fromCharCode(x) const concat = x=> y=> y.concat(x) const concatMap = f=> comp (fold (concat) ([])) (map (f)) const irand = x=> Math.floor(Math.random() * x) const sample = xs=> xs [irand (xs.length)] // range : make a range from x to y; [x...y] // Number -> Number -> [Number] const range = Y (f=> r=> x=> y=> x > y ? r : f ([...r, x]) (x+1) (y) ) ([]) // srand : make random string from list or ascii code ranges // [(Range a)] -> Number -> [a] const srand = comp (Y (f=> z=> rs=> x=> x === 0 ? z : f (z + sample (rs)) (rs) (x-1) ) ([])) (concatMap (map (char))) // idGenerator : make an identifier of specified length // Number -> String const idGenerator = srand ([ range (48) (57), // include 0-9 range (65) (90), // include AZ range (97) (122) // include az ]) console.log (idGenerator (6)) //=> TT688X console.log (idGenerator (10)) //=> SzaaUBlpI1 console.log (idGenerator (20)) //=> eYAaWhsfvLDhIBID1xRh

在我看來,如果不添加神奇的、做太多事情的功能,很難超越idGenerator的清晰度。

可能會略有改善

// ord : convert char to ascii code
// Char -> Number
const ord = x => x.charCodeAt(0)

// idGenerator : make an identifier of specified length
// Number -> String
const idGenerator = srand ([
  range (ord('0')) (ord('9')),
  range (ord('A')) (ord('Z')),
  range (ord('a')) (ord('z'))
])

玩得開心。 讓我知道你喜歡/學習什么^_^

隨機數值(最多 16 位)

/**
 * Random numeric value (up to 16 digits)
 * @returns {String}
 */
function randomUid () {
  return String(Math.floor(Math.random() * 9e15))
}

// randomUid() -> "3676724552601324"

這是一種不同的方法,按基數固定長度,沒有 RegExp 替換缺少(基於@bendytree 的回答);

function rand(base) {
    // default base 10
    base = (base >= 2 && base <= 36) ? base : 10;
    for (var i = 0, ret = []; i < base; i++) {
        ret[i] = ((Math.random() * base) | 0).toString(base)
            // include 0-9a-zA-Z?
            // [Math.random() < .5 ? 'toString' : 'toUpperCase']();
    }
    return ret.join('');
}

教人釣魚:

程序員用激光切紙,而不是電鋸。 使用邊緣、特定於語言的方法來生成最小、最模糊的代碼很可愛,但永遠不會提供完整的解決方案。 您必須使用正確的工具來完成這項工作。

你要的是一串字符,字符用字節表示。 而且,我們可以在 JavaScript 中使用一個數字來表示一個字節。 那么,我們應該生成這些數字的列表,並將它們轉換為字符串。 您不需要 Date 或 base64; Math.random() 會給你一個數字, String.fromCharCode() 會把它變成一個字符串。 簡單的。

但是,哪個數字等於哪個字符? UTF-8 是 Web 上用於將字節解釋為字符的主要標准(盡管 JavaScript 在內部使用 UTF-16,但它們是重疊的)。 程序員解決這個問題的方法是查看文檔。

UTF-8 以 0 到 128 之間的數字列出鍵盤上的所有鍵。有些是非打印的。 只需在隨機字符串中挑選出您想要的字符,然后使用隨機生成的數字搜索它們。

Bellow 是一個函數,它采用幾乎無限的長度,在循環中生成一個隨機數,並搜索低 128 個 UTF-8 代碼中的所有打印字符。 熵是固有的,因為並非所有隨機數每次都會命中(非打印字符、空格等)。 當您添加更多字符時,它的執行速度也會更快。

我已經包含了線程中討論的大部分優化:

  • 雙波浪號比 Math.floor 快
  • “if”語句比正則表達式更快
  • 推送到數組比字符串連接更快

 function randomID(len) { var char; var arr = []; var len = len || 5; do { char = ~~(Math.random() * 128); if (( (char > 47 && char < 58) || // 0-9 (char > 64 && char < 91) || // AZ (char > 96 && char < 123) // az // || (char > 32 && char < 48) // !"#$%&,()*+'-./ // || (char > 59 && char < 65) // <=>?@ // || (char > 90 && char < 97) // [\]^_` // || (char > 123 && char < 127) // {|}~ ) //security conscious removals: " ' \ ` //&& (char != 34 && char != 39 && char != 92 && char != 96) ) { arr.push(String.fromCharCode(char)) } } while (arr.length < len); return arr.join('') } var input = document.getElementById('length'); input.onfocus = function() { input.value = ''; } document.getElementById('button').onclick = function() { var view = document.getElementById('string'); var is_number = str => ! Number.isNaN( parseInt(str)); if ( is_number(input.value)) view.innerText = randomID(input.value); else view.innerText = 'Enter a number'; }
 #length { width: 3em; color: #484848; } #string { color: #E83838; font-family: 'sans-serif'; word-wrap: break-word; }
 <input id="length" type="text" value='#'/> <input id="button" type="button" value="Generate" /> <p id="string"></p>

為什么要用這種乏味的方式呢? 因為你能。 你是程序員。 你可以讓電腦做任何事! 此外,如果你想要一串希伯來字符怎么辦? 這並不難。 在 UTF-8 標准中找到這些字符並搜索它們。 從這些 McDonald 方法中解脫出來,比如 toString(36)。

有時,下降到較低的抽象級別是創建真正解決方案所需要的。 了解手頭的基本原則可以讓您根據需要自定義代碼。 也許您想要一個無限生成的字符串來填充循環緩沖區? 也許您希望所有生成的字符串都是回文? 為什么要讓自己退縮?

我制作了一個字符串原型,它可以生成一個給定長度的隨機字符串。

如果你想要特殊的字符,你也可以指定,你可以避免一些。

/**
 * STRING PROTOTYPE RANDOM GENERATOR
 * Used to generate a random string
 * @param {Boolean} specialChars
 * @param {Number} length
 * @param {String} avoidChars
 */
String.prototype.randomGenerator = function (specialChars = false, length = 1, avoidChars = '') {
    let _pattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    _pattern += specialChars === true ? '(){}[]+-*/=' : '';
    if (avoidChars && avoidChars.length) {
        for (let char of avoidChars) {
            _pattern = _pattern.replace(char, '');
        }
    }
    let _random = '';
    for (let element of new Array(parseInt(length))) {
        _random += _pattern.charAt(Math.floor(Math.random() * _pattern.length));
    }
    return _random;
};

你可以這樣使用:

// Generate password with specialChars which contains 10 chars and avoid iIlL chars
var password = String().randomGenerator(true, 10, 'iIlL');

希望能幫助到你。

隨機 unicode 字符串

此方法將返回帶有任何受支持的 unicode 字符的隨機字符串,這不是 OP 要求的 100%,而是我正在尋找的:

function randomUnicodeString(length){
    return Array.from({length: length}, ()=>{
        return String.fromCharCode(Math.floor(Math.random() * (65536)))
    }).join('')
}

基本原理

這是谷歌搜索“隨機字符串 javascript”時的最高結果,但 OP 只要求 a-zA-Z0-9。

正如這里的幾個人所指出的,將Math.random()的結果直接傳遞給.string(36)有幾個問題。

它的隨機性很差。 生成的字符數各不相同,平均而言取決於浮點數在 Javascript 中如何工作的棘手細節。 如果我嘗試生成 11 個或更少的字符,但不超過 11 個,它似乎可以工作。而且它不靈活。 沒有簡單的方法來允許或禁止某些字符。

對於使用 lodash 的任何人,我都有一個緊湊的解決方案,它沒有這些問題:

_.range(11).map(i => _.sample("abcdefghijklmnopqrstuvwxyz0123456789")).join('')

如果要允許某些字符(如大寫字母)或禁止某些字符(如l1等模棱兩可的字符),請修改上面的字符串。

我只是寫了一個簡單的包來生成一個給定大小、種子和掩碼的隨機令牌。 供參考。

@sibevin/random-token - https://www.npmjs.com/package/@sibevin/random-token

import { RandomToken } from '@sibevin/random-token'

RandomToken.gen({ length: 32 })
// JxpwdIA37LlHan4otl55PZYyyZrEdsQT

RandomToken.gen({ length: 32, seed: 'alphabet' })
// NbbtqjmHWJGdibjoesgomGHulEJKnwcI

RandomToken.gen({ length: 32, seed: 'number' })
// 33541506785847193366752025692500

RandomToken.gen({ length: 32, seed: 'oct' })
// 76032641643460774414624667410327

RandomToken.gen({ length: 32, seed: 'hex' })
// 07dc6320bf1c03811df7339dbf2c82c3

RandomToken.gen({ length: 32, seed: 'abc' })
// bcabcbbcaaabcccabaabcacbcbbabbac

RandomToken.gen({ length: 32, mask: '123abcABC' })
// vhZp88dKzRZGxfQHqfx7DOL8jKTkWUuO

像這樣擴展 String 對象怎么樣。

String.prototype.random = function(length) {
   var result = '';
   for (var i = 0; i < length; i++) {
      result += this.charAt(Math.floor(Math.random() * this.length));
   }

   return result;
};

使用它:

console.log("ABCDEFG".random(5));
function generate(length) {
  var letters = ["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","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"];
  var IDtext = "";
  var i = 0;
  while (i < length) {
    var letterIndex = Math.floor(Math.random() * letters.length);
    var letter = letters[letterIndex];
    IDtext = IDtext + letter;
    i++;
  }
  console.log(IDtext)
}
[..."abcdefghijklmnopqrsuvwxyz0123456789"].map((e, i, a) => a[Math.floor(Math.random() * a.length)]).join('')

生成具有 aA-zZ 和 0-9 字符集合的隨機字符串。 只需使用長度參數調用此函數。

所以要回答這個問題: generateRandomString(5)

generateRandomString(length){
    let result = "", seeds

    for(let i = 0; i < length - 1; i++){
        //Generate seeds array, that will be the bag from where randomly select generated char
        seeds = [
            Math.floor(Math.random() * 10) + 48,
            Math.floor(Math.random() * 25) + 65,
            Math.floor(Math.random() * 25) + 97
        ]
        
        //Choise randomly from seeds, convert to char and append to result
        result += String.fromCharCode(seeds[Math.floor(Math.random() * 3)])
    }

    return result
}

生成不帶數字的字符串的版本:

generateRandomString(length){
    let result = "", seeds

    for(let i = 0; i < length - 1; i++){
        seeds = [
            Math.floor(Math.random() * 25) + 65,
            Math.floor(Math.random() * 25) + 97
        ]
        result += String.fromCharCode(seeds[Math.floor(Math.random() * 2)])
    }

    return result
}

另一種從字符A-Za-z0-9中隨機化字符串的好方法:

function randomString(length) {
    if ( length <= 0 ) return "";
    var getChunk = function(){
        var i, //index iterator
            rand = Math.random()*10e16, //execute random once
            bin = rand.toString(2).substr(2,10), //random binary sequence
            lcase = (rand.toString(36)+"0000000000").substr(0,10), //lower case random string
            ucase = lcase.toUpperCase(), //upper case random string
            a = [lcase,ucase], //position them in an array in index 0 and 1
            str = ""; //the chunk string
        b = rand.toString(2).substr(2,10);
        for ( i=0; i<10; i++ )
            str += a[bin[i]][i]; //gets the next character, depends on the bit in the same position as the character - that way it will decide what case to put next
        return str;
    },
    str = ""; //the result string
    while ( str.length < length  )
        str += getChunk();
    str = str.substr(0,length);
    return str;
}

npm 模塊anyid提供靈活的 API 來生成各種字符串 ID/代碼。

const id = anyid().encode('Aa0').length(5).random().id();

在下面的代碼中,我正在為 8 個字符生成隨機代碼

function RandomUnique(){
                    var charBank = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789";
                    var random= '';
                    var howmanycharacters = 8;
                    for (var i = 0; i < howmanycharacters ; i++) {
                        random+= charBank[parseInt(Math.random() * charBank.lenght)];
                    }
                    return random;
                }
        var random = RandomUnique();
        console.log(random);

試試這個,我每次都用什么:

 function myFunction() { var hash = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012346789"; var random8 = ''; for(var i = 0; i < 5; i++){ random8 += hash[parseInt(Math.random()*hash.length)]; } console.log(random8); document.getElementById("demo").innerHTML = "Your 5 character string ===> "+random8; }
 <!DOCTYPE html> <html> <body> <p>Click the button to genarate 5 character random string .</p> <button onclick="myFunction()">Click me</button> <p id="demo"></p> </body> </html>

很簡單

function getRandomColor(){
  var color='';
  while(color.length<6){
    color=Math.floor(Math.random()*16777215).toString(16);
  }
  return '#'+color;
}

您可以使用 base64:

function randomString(length)
{
    var rtn = "";

    do {
        rtn += btoa("" + Math.floor(Math.random() * 100000)).substring(0, length);
    }
    while(rtn.length < length);

    return rtn;
}

遞歸解決方案:

function generateRamdomId (seedStr) {
const len = seedStr.length
console.log('possibleStr', seedStr , ' len ', len)
if(len <= 1){
    return seedStr
}
const randomValidIndex  = Math.floor(Math.random() * len)
const randomChar = seedStr[randomValidIndex]
const chunk1 = seedStr.slice(0, randomValidIndex)
const chunk2 = seedStr.slice(randomValidIndex +1)
const possibleStrWithoutRandomChar = chunk1.concat(chunk2)

return randomChar + generateRamdomId(possibleStrWithoutRandomChar)

}

你可以使用你想要的種子,如果你不想要,不要重復字符。 例子

generateRandomId("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") 

簡單方法:

function randomString(length) {
    let chars = [], output = '';
    for (let i = 32; i < 127; i ++) {
        chars.push(String.fromCharCode(i));
    }
    for (let i = 0; i < length; i ++) {
        output += chars[Math.floor(Math.random() * chars.length )];
    }
    return output;
}

如果您想要更多或更少的字符,請將“127”更改為其他字符。

審查

許多答案基於技巧Math.random().toString(36)但這種方法的問題是 Math.random 並不總是產生在基數 36 中至少有 5 個字符的數字,例如

 let testRnd = n => console.log(`num dec: ${n}, num base36: ${n.toString(36)}, string: ${n.toString(36).substr(2, 5)}`); [ Math.random(), // and much more less than 0.5... 0.5, 0.50077160493827161, 0.5015432098765432, 0.5023148148148148, 0.5030864197530864, // and much more.... 0.9799597050754459 ].map(n=>testRnd(n)); console.log('... and so on');
 Each of below example (except first) numbers result with less than 5 characters (which not meet OP question requirements)

這是允許手動查找此類數字的“生成器”

 function base36Todec(hex) { hex = hex.split(/\./); return (parseInt(hex[1],36))*(36**-hex[1].length)+ +(parseInt(hex[0],36)); } function calc(hex) { let dec = base36Todec(hex); msg.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${dec.toString(36)}</b>` } function calc2(dec) { msg2.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${(+dec).toString(36)}</b>` } let init="0.za1"; inp.value=init; calc(init);
 Type number in range 0-1 using base 36 (0-9,az) with less than 5 digits after dot<br> <input oninput="calc(this.value)" id="inp" /><div id="msg"></div> <br> If above <i>hex test</i> give more digits than 5 after dot - then you can try to copy dec number to below field and join some digit to dec num right side and/or change last digit - it sometimes also produce hex with less digits<br> <input oninput="calc2(this.value)" /><br><div id="msg2"></div>

我已經在這里給出了答案,所以我不會在這里提出另一個解決方案

以下代碼將使用 npm 包crypto-random-string生成包含[a-zA-Z0-9]大小的加密安全隨機字符串。 安裝它使用:

npm install crypto-random-string

要在集合 [a-zA-Z0-9] 中獲取 30 個字符的隨機字符串:

const cryptoRandomString = require('crypto-random-string');
cryptoRandomString({length: 100, type: 'base64'}).replace(/[/+=]/g,'').substr(-30);

摘要:我們在一個大的隨機 base64 字符串中替換 /、+、= 並獲取最后 N 個字符。

PS:substr中使用 -N

如果您無法輸入字符集,則使用String.fromCharCode和范圍Math.random允許您在任何 Unicode 代碼點范圍內創建隨機字符串。 例如,如果你想要17隨機藏文字符,你可以輸入ranstr(17,0xf00,0xfff) ,其中(0xf00,0xfff)對應藏文 Unicode 塊。 在我的實現中,如果您不指定代碼點范圍,生成器將輸出ASCII文本。

 function ranchar(a,b) { a = (a === undefined ? 0 : a); b = (b === undefined ? 127 : b); return String.fromCharCode(Math.floor(Math.random() * (b - a) + a)); } function ranstr(len,a,b) { a = a || 32; var result = ''; for(var i = 0; i < len; i++) { result += ranchar(a,b) } return result; } //Here are some examples from random Unicode blocks console.log('In Latin Basic block: '+ ranstr(10,0x0000,0x007f)) console.log('In Latin-1 Supplement block: '+ ranstr(10,0x0080,0x0ff)) console.log('In Currency Symbols block: ' + ranstr(10,0x20a0,0x20cf)) console.log('In Letterlike Symbols block: ' + ranstr(10,0x2100,0x214f)) console.log('In Dingbats block:' + ranstr(10,0x2700,0x27bf))

喜歡這個 SO 問題和他們的答案。 因此,提出了更明智和創造性的解決方案。 我想出了我的,它被包裝在一個函數中,該函數接收您想要獲取的字符串的長度加上一個模式參數來決定您希望它如何組合。

Mode是一個長度為 3 的字符串,它只接受 '1s' 和 '0s',它們定義了您希望在最終字符串中包含哪些字符子集。 它由 3 個不同的子集([0-9]、[AB]、[ab])分組

'100': [0-9]
'010': [A-B]
'101': [0-9] + [a-b]
'111': [0-9] + [A-B] + [a-b]

有 8 種可能的組合(2^N,有 N:#subsets)。 '000' 模式返回一個空字符串。

function randomStr(l = 1, mode = '111') {
    if (mode === '000') return '';
    const r = (n) => Math.floor(Math.random() * n);
    const m = [...mode].map((v, i) => parseInt(v, 10) * (i + 1)).filter(Boolean).map((v) => v - 1);
    return [...new Array(l)].reduce((a) => a + String.fromCharCode([(48 + r(10)), (65 + r(26)), (97 + r(26))][m[r(m.length)]]), '')
}

一個簡單的用例將是:

random = randomStr(50, '101')
// ii3deu9i4jk6dp4gx43g3059vss9uf7w239jl4itv0cth5tj3e
// Will give you a String[50] composed of [0-9] && [a-b] chars only.

這里的主要思想是使用 UNICODE 表,而不是像我在許多答案中看到的那樣隨機化十六進制。 這種方法的強大之處在於,您可以非常輕松地對其進行擴展,以包含 UNICODE 表的其他子集,其中包含隨機 int(16) 無法做到的少量額外代碼。

您可以使用Web Crypto 的 API

 console.log(self.crypto.getRandomValues(new Uint32Array(1))[0])

這里的原始答案)

function generateRandomStringLettersAndNumbers(maxLength): string {
  return crypto.randomBytes(maxLength).toString('hex').substring(0, maxLength);
}

我使用var randId = 'rand' + new Date().getTime();

最重要的是答案是完美的。 但我要添加的是非常好的快速生成任何隨機字符串值

 function randomStringGenerator(stringLength) { var randomString = ""; // Empty value of the selective variable const allCharacters = "'`~!@#$%^&*()_+-={}[]:;\'<>?,./|\\ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'"; // listing of all alpha-numeric letters while (stringLength--) { randomString += allCharacters.substr(Math.floor((Math.random() * allCharacters.length) + 1), 1); // selecting any value from allCharacters varible by using Math.random() } return randomString; // returns the generated alpha-numeric string } console.log(randomStringGenerator(10));//call function by entering the random string you want

或者

 console.log(Date.now())// it will produce random thirteen numeric character value every time. console.log(Date.now().toString().length)// print length of the generated string

//創建一個長度為10的隨機代碼,您可以隨意將其更改為您的

function createRandomCode(length) {
    let randomCodes = '';
    let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let charactersLength = characters.length;
    for (let i = 0; i < length; i++ ) {
        randomCodes += characters.charAt(Math.floor(Math.random() * charactersLength))
    }
    console.log("your reference code is: ".toLocaleUpperCase() + randomCodes);
 };
 createRandomCode(10)

這不是一個完美的解決方案,但它應該可以工作。 如果您遇到任何錯誤,請增加 Uint8Array() 構造函數中給出的值。 此方法的優點是它使用getRandomValues()方法生成加密強隨機值。

 var array = new Uint8Array(20); crypto.getRandomValues(array); var arrayEncoded = btoa(String.fromCharCode(...array)).split(''); var arrayFiltered = arrayEncoded.filter(value => { switch (value){ case "+" : return false; case "/" : return false; case "=" : return false; default : return true; } }); var password = arrayFiltered.slice(0,5).join(''); console.log(password);

精簡版

 var array = new Uint8Array(20); crypto.getRandomValues(array); var password = btoa(String.fromCharCode(...array)).split('').filter(value => { return !['+', '/' ,'='].includes(value); }).slice(0,5).join(''); console.log(password);

要從數組生成哈希作為鹽,在本例中為[0,1,2,3] ,通過這種方式,我們可以稍后檢索哈希以填充條件。

只需提供一個隨機陣列,或用作陣列的額外安全和快速指紋。

 /* This method is very fast and is suitable into intensive loops */ /* Return a mix of uppercase and lowercase chars */ /* This will always output the same hash, since the salt array is the same */ console.log( btoa(String.fromCharCode(...new Uint8Array( [0,1,2,3] ))) ) /* Always output a random hex hash of here: 30 chars */ console.log( btoa(String.fromCharCode(...new Uint8Array( Array(30).fill().map(() => Math.round(Math.random() * 30)) ))) )

使用來自加密 API 的 HMAC,更多信息: https ://stackoverflow.com/a/56416039/2494754

這是 CoffeeScript 中的一個示例:

String::add_Random_Letters   = (size )->
                                         charSet = 'abcdefghijklmnopqrstuvwxyz'
                                         @ + (charSet[Math.floor(Math.random() * charSet.length)]  for i in [1..size]).join('')

哪個可以用

value = "abc_"
value_with_exta_5_random_letters = value.add_Random_Letters(5)

//返回一個隨機字母

let alpha = "ABCDEFGHIGKLMNOPQRSTUVWXYZ";
console.log(alpha.charAt(Math.floor(Math.random() * alpha.length)));

這是 Coffeescript 版本的一行代碼

genRandomString = (length,set) -> [0...length].map( -> set.charAt Math.floor(Math.random() * set.length)).join('')

用法:

genRandomString 5, 'ABCDEFTGHIJKLMNOPQRSTUVWXYZ'

輸出:

'FHOOV' # random string of length 5 in possible set A~Z

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM