web-dev-qa-db-ja.com

JavaScriptでランダムな文字列を生成する

集合[a-zA-Z0-9]からランダムに選んだ文字からなる5文字の文字列が欲しいのですが。

JavaScriptでこれを行うための最良の方法は何ですか?

1348
Tom Lehman

私はこれがあなたのために働くと思います:

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

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

  return text;
}

console.log(makeid());

1873
csharptest.net

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

注:上記のアルゴリズムには、次のような弱点があります。

  • 浮動小数点を文字列化すると末尾のゼロが削除されるため、0から6文字の間のどこかに生成されます。
  • それは恐ろしいほど複雑な浮動小数点数を文字列化するために使われるアルゴリズムに深く依存します。 (論文 「浮動小数点数を正確に印刷する方法」 を参照。)
  • 実装によってはMath.random()は予測可能な( "ランダムに見える"が実際にはランダムではない)出力を生成するかもしれません。結果の文字列は、一意性や予測不可能性を保証する必要がある場合には適していません。
  • たとえそれが6つの一様にランダムで予測不可能な文字を生成したとしても、 誕生日のパラドックス のために、たった約50,000の文字列を生成した後に重複を見ることが期待できます。 (sqrt(36 ^ 6)= 46656)
1969
doubletap

Math.random はこの種のことには良くありません

オプション1

これをserver-側にできるのなら、 crypto モジュールを使うだけです。

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

// "bb5dc8842ca31d4603d6aa11448d1654"

結果の文字列は、生成したランダムバイトの2倍の長さになります。 16進数にエンコードされた各バイトは2文字です。 20バイトは40文字の16進数になります。


オプション2

これをclient-sideしなければならないなら、おそらくuuidモジュールを試してみてください。

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

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

オプション3

これをclient-sideで行う必要があり、古いブラウザをサポートする必要がない場合は、依存関係なしでそれを実行できます。

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

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

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

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

302
user633183

短く、簡単、そして信頼できる

ここにある最高評価の回答の一部とは対照的に、正確に5つのランダムな文字を返します。

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

これが doubletapの優れた答え の改善です。オリジナルには、ここで対処する2つの欠点があります。

まず、他の人が述べたように、短い文字列や空の文字列(乱数が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. 数字を36進数の文字列に変換します。つまり、0から9の文字とaからzの文字を使用します。
  3. ゼロで埋めます(最初の問題を解決します)。
  4. 先頭の「0」を切り取る接頭辞と余分なパディングゼロ.
  5. 空の文字列と短いランダムな文字列を区切り文字として結合して、N文字以上になるように文字列を十分に繰り返します。
  6. 文字列からN文字だけスライスします。

さらなる考え:

  • このソリューションでは大文字は使用されませんが、ほとんどの場合(駄目なことは意図されていません)、問題にはなりません。
  • 元の回答のN = 16の最大文字列長はChromeで測定されます。 FirefoxではN = 11です。しかし、説明したように、2番目の解決策は、ランダムさを追加することではなく、要求された文字列長をサポートすることです。したがって、それほど大きな違いはありません。
  • 少なくともMath.random()によって返される結果が均等に分散されている限り、返されるすべての文字列は同じ確率で返されます(これは暗号強度のランダム性ではありません)。
  • サイズNのすべての文字列が返されるとは限りません。 2番目の解決策ではこれは明白ですが(小さい文字列が単純に複製されるため)、元の答えではこれは真実です。なぜなら基数36への変換で最後の数ビットは元のランダムビットの一部ではないからです。具体的には、Math.random()。toString(36)の結果を見ると、最後の文字が均等に配置されていないことがわかります。繰り返しますが、ほとんどの場合、問題にはなりませんが、短い文字列(N = 1など)が影響を受けないように、ランダムな文字列の末尾ではなく先頭から最後の文字列をスライスします。

更新:

これが私が思い付いた他の2つの他の機能的なスタイルのライナーです。それらは、次の点で上記のソリューションとは異なります。

  • それらは明示的な任意のアルファベットを使用します(より一般的で、大文字と小文字の両方を要求した元の質問に適しています)。
  • 長さNのすべての文字列は、返される確率が同じです(つまり、文字列には繰り返しが含まれません)。
  • これらはtoString(36)トリックではなくマップ関数に基づいているため、よりわかりやすく理解しやすくなります。

だから、あなたの選んだアルファベットは

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

それから、これら2つは互いに同等です、それであなたはどちらがあなたにとって直感的である方を選ぶことができます:

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

編集:

私は qubyte そして Martijn de Milliano が後者に似た解決策を思いついたようだ(kudos!)。一見すると短く見えるわけではないので、誰かが本当にワンライナーを望んでいる場合に備えて、私はとにかくここに置いておきます:-)

また、すべてのソリューションで 'new Array'を 'Array'に置き換えて、さらに数バイトを削り取ってください。

139
amichair

このようなものはうまくいくはずです

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');
90
CaffGeek

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

67
kennebec

slicesubstring より短いため、最もコンパクトなソリューションです。文字列の末尾から減算すると、 random functionによって生成される浮動小数点記号を回避できます。

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

あるいは

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

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

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

59
Valentin

ランダム文字列ジェネレータ(英数字|英数字|数値)

/**
 * RANDOM STRING GENERATOR
 *
 * Info:      http://stackoverflow.com/a/27872144/383904
 * Use:       randomString(length [,"A"] [,"N"] );
 * Default:   return a random alpha-numeric string
 * Arguments: If you use the optional "A", "N" flags:
 *            "A" (Alpha flag)   return random a-Z string
 *            "N" (Numeric flag) return random 0-9 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;
}
randomString(10);        // "4Z8iNQag9v"
randomString(10, "A");   // "aUkZuHNcWw"
randomString(10, "N");   // "9055739230"

楽しむ。 jsBinデモ


上記では目的の(A/N、A、N)出力に対して追加のチェックを使用していますが、 理解を深めるために必須項目(英数字のみ)に分けてみましょう

  • 引数を受け取る関数を作成します(ランダムなString結果の望ましい長さ)
  • ランダムな文字を連結するためにvar str = "";のような空の文字列を作成します
  • ループ内 Randインデックス番号を作成 から 0から61 (0..9 + A..Z + a..z = 62)
  • 条件付きロジック から 調整/修正Rand (0..61なので)を作成して、それをある数だけ増やし(下記の例を参照)、正しいCharCode番号と関連する文字を元に戻します。
  • ループ内でstr a String.fromCharCode( incremented Rand )に連結

文字テーブル とその 範囲 を想像してみましょう。

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

条件付き演算 logic 上の表から:

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

上記の説明に従えば、これを作成できるはずです 英数字スニペット

jsBinデモ

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

またはする場合は

function randomString( n ) {
  var r="";
  while(n--)r+=String.fromCharCode((r=Math.random()*62|0,r+=r>9?(r<36?55:61):48));
  return r;
}
45
Roko C. Buljan

es6スプレッド演算子 の新しいバージョン

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

  • 30は任意の数字です。任意のトークン長を選択できます
  • 36は、 numeric.toString() に渡すことができる最大基数です。つまり、すべての 数字とa-z小文字
  • 2は、次のようなランダムな文字列から2番目の番号を選択するために使用されます。"0.mfbiohx64i"0.の後にインデックスを作成できます
41
Or Duan

最も簡単な方法は次のとおりです。 

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

これは現在時刻に基づいて5文字のランダムな文字列を生成します。出力例は4mtxjまたは4mv90または4mwp1です。

これの問題点は、同じ秒に2回呼び出すと、同じ文字列が生成されることです。 

より安全な方法は次のとおりです。 

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

これは4または5文字のランダムな文字列を生成し、常に異なっています。出力例は30jzm1r591、または4su1aのようになります

どちらの方法でも、最初の部分は乱数を生成します。 .toString(36)部分は、数値をbase36(英数字)表現にキャストします。 

29

これは簡単なライナーです。 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"]();});
20
bendytree

私は誰もがそれをすでに正しく理解していることを知っています、しかし私は可能な限り最も軽量な方法でこれを試してみる気がしました(コードではなく、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の構文が非常に優れていることを実際に示していると思います。

17
Roderick

Lodash または Underscore を使用している場合は、とても簡単です。

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

これが私が作成した方法です。
大文字と小文字の両方を含む文字列を作成します。
さらに、英数字の文字列を作成する関数も含めました。

実用例:
http://jsfiddle.net/greatbigmassive/vhsxs/ /(アルファのみ)
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)));
}
13
Adam

underscorejs を使用すると仮定すると、たった2行でランダムな文字列を生成することができます。

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

誰かが一度にメモリを割り当てるワンライナー(あなたの便宜のためにそのようにフォーマットされてはいませんが)に興味があるなら(しかし小さい文字列のためにそれは本当に重要ではないので)

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

5は、必要な文字列の長さに置き換えることができます。 Array(5)によって作成されたスパース配列では機能しないmap関数の解決策として、 このポスト の@AriyaHidayatに感謝します。

11

要件[a-zA-Z0-9]と長さ= 5を満たすには

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

小文字、大文字、数字が表示されます。

11
Sergio Cabral

高速で改良されたアルゴリズム制服を保証しない(コメント参照)。

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

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    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);
        }
    }

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

    return result;
}
8
yaroslav

たとえばランダムな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));

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

これはなるべくきれいです。それも速いです、 http://jsperf.com/ay-random-string

6
Gajus

私は小文字と大文字の両方をサポートするためのきれいな解決策を見つけませんでした。

小文字のみのサポート:

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を変更して必要な長さに調整してください。

6
ravishi

"ランダムな文字列が必要です"質問(どの言語でも)への応答の問題は、実際にはすべてのソリューションがの欠陥のあるプライマリ仕様を使用している文字列の長さ。質問自体は、ランダムな文字列が必要な理由をめったに明らかにしませんが、長さのランダムな文字列、たとえば8はほとんど必要ありません。常に必要なのは、unique strings、たとえば、何らかの目的で識別子として使用する場合。

strictly unique文字列を取得するには、2つの主な方法があります:決定論的(ランダムではない)とストア/比較(面倒な)です。私たちは何をしますか?私たちは幽霊をあきらめます。代わりにprobabilistic uniquenessを使用します。つまり、文字列が一意にならないという(わずかではあるが)リスクがあることを受け入れます。 衝突確率 および entropy 役に立ちます。

したがって、繰り返しのリスクが少ないいくつかの文字列が必要であるとして、不変の必要性を言い換えます。具体的な例として、500万個のIDを生成したいとします。新しい文字列を保存して比較したり、ランダムにしたりしたくないので、繰り返しのリスクを受け入れます。例として、1兆回の繰り返しの可能性のうち1未満のリスクがあるとします。それでは、どのくらいの長さの文字列が必要ですか?まあ、その質問は使用される文字に依存するため、指定不足です。しかし、もっと重要なことは、見当違いです。必要なのは、文字列の長さではなく、文字列のエントロピーの仕様です。エントロピーは、いくつかの文字列の繰り返しの確率に直接関係する場合があります。文字列の長さはできません。

そして、これは EntropyString のようなライブラリが役立つところです。 entropy-stringを使用して、500万の文字列で1兆回未満の確率で1未満のランダム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文字の文字セットを使用します。他にも定義済みの文字セットがあり、独自の文字を指定することもできます。たとえば、上記と同じエントロピーを持つが、16進文字を使用した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」

使用される文字セット内の文字の総数の違いによる文字列の長さの違いに注意してください。指定された数の潜在的な文字列で繰り返されるリスクは同じです。文字列の長さは異なります。そして何よりも、繰り返しの可能性と文字列の潜在的な数は明示的です。文字列の長さを推測する必要はもうありません。

6
dingo sky

これは確かにうまくいく

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

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

coderain を使用できます。与えられたパターンに従ってランダムなコードを生成するためのライブラリです。 #を、数字だけでなく大文字と小文字のプレースホルダーとして使用します。

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

大文字のAや数字の9のような他のプレースホルダーがあります。

便利なことは、.next()を呼び出すことは常にあなたにユニークな結果を与えるので、重複について心配する必要はないということです。

これは ユニークなランダムコードのリストを生成するデモアプリケーションです

完全開示:私はcoderainの作者です。

4
Lukasz Wiktor

Date.now().toString(36) あまりランダムではありませんが、呼び出すたびに短くてまったくユニークです。

4
Swergas

大文字と小文字を区別しない英数字

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

3
Ali

これが#1答えのためのテストスクリプトです(ありがとう@ csharptest.net)

このスクリプトはmakeid()1 million回実行されますが、ご覧のとおり5つのisntは非常にユニークです。 10のcharの長さでそれを実行することはかなり信頼できます。私はそれを約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');
3

このコンパクトな小さなトリックはどうですか。

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

これは多くの答えをまとめたものです。

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ヶ月間それを使ってきました素晴らしい結果があります。

2
miodus

これが私が使ったものです。ここでカップルの組み合わせ。私はそれをループで使います、そしてそれが作り出すそれぞれのIDはユニークです。 5文字ではないかもしれませんが、ユニークであることが保証されています。

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

ライブラリが可能な場合は、Chance.jsが役に立ちます。 http://chancejs.com/#string

2
Luca Bonavita

GertasとDragonが提起した問題に答えることで、Doubletapの優雅な例を広げましょう。これらのまれなnull状況をテストするためにwhileループを追加し、文字を5つに制限するだけです。 

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/

2
Steven DAmico

大文字と小文字および数字(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バイト必要です(文字リストのため)。

1
Waruyama

以下は、ベースごとに固定長を使用した別のアプローチです。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('');
}
1
K-Gun

同じくダブルタップの答えに基づいて、これは任意の長さのランダムに要求される文字を処理し(下のみ)、十分な文字が集められるまで乱数を生成し続けます。

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

私は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);
1
Dwayne
"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('');};

最初の/呼び出し元の文字列の長さを持つランダムな英数字文字列を生成します

1
nclu

これは doubletapanswer を少し改良したものです。 Math.random()が0、0.5、0.25、0.125などを返す場合、 gertas のケースに関するコメントを考慮します。

((Math.random()+3*Number.MIN_VALUE)/Math.PI).toString(36).slice(-5)
  1. 最小のfloatをMath.random()に追加することで、ゼロがtoStringに渡されるのを防ぎます。
  2. これはtoStringに渡される数がほぼ無理数で割ることによって十分な桁数を持つことを保証します。
1
ceving

これは、変数cに5文字の英数字を格納します。

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

釣りをする人に教える:

プログラマーはチェーンソーではなくレーザーで紙を切る。フリンジを使用して、最小の、最も難読化されたコードを生成するための言語固有の方法は、すべて可愛いですが、完全なソリューションを提供することは決してありません。あなたはその仕事に合った道具を使わなければなりません。 

欲しいのは文字列で、文字はバイトで表されます。そして、数値を使って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) || // A-Z
        (char > 96 && char < 123) // a-z

        // || (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標準でそれらの文字を見つけて、それらを検索してください。 toString(36)のようなこれらのマクドナルドメソッドからあなた自身を解放してください。

時には、より低い抽象レベルに落とし込むことが、実際のソリューションを作成するために必要なことです。当面の基本原則を理解することで、あなたが望むようにコードをカスタマイズすることができます。無限に生成された文字列で循環バッファを埋める必要があるかもしれません。たぶんあなたはあなたの生成された文字列のすべてを回文にしたいですか?どうして腰を下ろすの?

1
Duco
",,,,,".replace(/,/g,function (){return "AzByC0xDwEv9FuGt8HsIrJ7qKpLo6MnNmO5lPkQj4RiShT3gUfVe2WdXcY1bZa".charAt(Math.floor(Math.random()*62))});
1
guest271314

ランダムなUnicode文字列

このメソッドは、サポートされているUnicode文字のいずれかを含むランダムな文字列を返します。これは、OPが要求する100%ではなく、探しているものです。

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

根拠

これは "random string javascript"を検索したときのgoogleのトップ結果ですが、OPはa-zA-Z0-9のみを要求します。 

1
Automatico

ランダムな数値(最大16桁)

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

// randomUid() -> "3676724552601324"
1
artnikpro

私はvar randId = 'Rand' + new Date().getTime();を使います

1
CMS

これはFirefoxのクロムコード(アドオンなど)のためのものです

それはあなたの研究の数時間を節約することができます。

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

文字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;
}
0
Slavik Meltser

与えられた長さのランダムな文字列を生成できる文字列プロトタイプを作りました。

あなたが特別な文字がほしいと思うならばあなたはまたあなたを守ることができます、そしてあなたはいくつかを避けることができます。

/**
 * 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');

それが役に立てば幸い。

0
Sparw

ここで何人かの人々が指摘したように、Math.random()の結果を直接.string(36)に渡すことにはいくつかの問題があります。

ランダム性が低いです。生成される文字数はさまざまで、平均してJavascriptで浮動小数点数がどのように機能するかについての細かい詳細によって異なります。私が11文字以下にしようとしているのであればうまくいくようですが、11文字以上ではうまくいきません。そして柔軟ではありません。特定の文字を許可または禁止する簡単な方法はありません。

私はlodashを使っている人のためにこれらの問題を抱えていないコンパクトな解決策を持っています:

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

特定の文字(大文字など)を許可したり、特定の文字を禁止したり(l1などのあいまいな文字など)したい場合は、上記の文字列を変更します。

0
Elias Zamaria

下のコードで私は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);
0

機能的アプローチこの答えは実用的です - - - 機能的前提条件はあなたのアプリの他の部分で活用することができます。パフォーマンスはおそらくジャンクですが、書くのはとても楽しかったです。

// 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 A-Z
  range (97) (122)  // include a-z
])

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

楽しんでください。あなたの好きなことを教えてください/学びましょう^ _ ^

0
user633183

すべての答えは完璧です。しかし、私はランダムな文字列値を生成するためにどれが非常に良くて速いかを付け加えています

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
0
Parth Raval

再帰的な解決策:

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") 
0
Pascual Muñoz

とても簡単

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

Map関数でthisArgとして文字を入れると "one-liner"が作成されます。

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

あなたはbase64を使用することができます:

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

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

    return rtn;
}
0
Antinous

これを試してみて、私は毎回使用するもの:

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>

const c = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const s = Array.from({length:5}, _ => c[Math.floor(Math.random()*c.length)]).join('')
0
Nahuel Greco

これが私の(TypeScriptを使った)アプローチです。

現代のjsとクリーンなコードを使った簡単な解決策は見当たらなかったので、私はさらに別の応答を書くことにしました。

const DEFAULT_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

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

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

generateId(5); // jNVv7
0
pie6k

与えられたサイズ、シード、マスクを使ってランダムなトークンを生成する簡単なパッケージを書くだけです。ちなみに。

@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
0
Sibevin Wang

下記はどうでしょうか...これは本当にランダムな値を生成します。

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

Npmモジュール anyid はさまざまな種類の文字列ID /コードを生成するための柔軟なAPIを提供します。

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