Saya ingin 5 karakter string yang terdiri dari karakter yang dipilih secara acak dari set [a-zA-Z0-9]
.
Apa's cara terbaik untuk melakukan ini dengan JavaScript?
let r = Math.random().toString(36).substring(7);
console.log("random", r);
Catatan: algoritma di atas mempunyai kelemahan:
Matematika.random()
dapat menghasilkan diprediksi ("random-cari" tapi tidak benar-benar acak) output tergantung pada implementasi. String yang dihasilkan tidak cocok ketika anda perlu untuk menjamin keunikan atau ketidakpastian.Saya pikir ini akan bekerja untuk anda:
fungsi makeid(panjang) { var hasil = ''; var karakter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = karakter.panjang; for ( var i = 0; i < length; i++ ) { hasil += karakter.charAt(Matematika.floor(Math.random() * charactersLength)); } return hasil; }
konsol.log(makeid(5));
Matematika.random buruk untuk hal semacam ini
1
Jika anda're dapat melakukan hal ini server-sisi, hanya menggunakan crypto modul -
var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');
// "bb5dc8842ca31d4603d6aa11448d1654"
String yang dihasilkan akan menjadi dua kali lebih lama sebagai random byte yang anda hasilkan, masing-masing byte yang dikodekan ke hex adalah 2 karakter. 20 byte akan menjadi 40 karakter hex.
Pilihan 2
Jika anda memiliki untuk melakukan hal ini klien-sisi, mungkin mencoba uuid modul -
var uuid = require("uuid");
var id = uuid.v4();
// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"
3
Jika anda memiliki untuk melakukan hal ini klien-sisi dan anda don't harus mendukung browser lama, anda bisa melakukannya tanpa ketergantungan -
// dec2hex :: Integer -> String
// i.e. 0-255 -> '00'-'ff'
function dec2hex (dec) {
return ('0' + dec.toString(16)).substr(-2)
}
// generateId :: Integer -> String
function generateId (len) {
var arr = new Uint8Array((len || 40) / 2)
window.crypto.getRandomValues(arr)
return Array.from(arr, dec2hex).join('')
}
console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"
console.log(generateId(20))
// "c1a050a4cd1556948d41"
Untuk informasi lebih lanjut tentang kripto.getRandomValues
-
`kripto.getRandomValues () metode memungkinkan anda mendapatkan acak cryptographically kuat nilai-nilai. Array yang diberikan sebagai parameter diisi dengan angka acak (random dalam kriptografi makna).
Berikut ini's sedikit konsol contoh -
> 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 ]
Untuk IE11 mendukung anda dapat menggunakan -
(window.crypto || window.msCrypto).getRandomValues(arr)
Untuk browser cakupan melihat https://caniuse.com/#feat=getrandomvalues
Kembali tepat 5 karakter acak, sebagai lawan untuk beberapa nilai atas jawaban-jawaban yang ditemukan di sini.
Math.random().toString(36).substr(2, 5);
Berikut ini's perbaikan pada doubletap's jawaban yang sangat baik. Asli memiliki dua kelemahan yang dibahas di sini:
Pertama, sebagai orang lain telah disebutkan, itu kecil kemungkinan menghasilkan string pendek atau bahkan string kosong (jika nomor acak adalah 0), yang dapat memecah aplikasi. Berikut adalah solusinya:
(Math.random().toString(36)+'00000000000000000').slice(2, N+2)
Kedua, baik asli dan solusi atas batas string ukuran N 16 karakter. Berikut ini akan mengembalikan sebuah string ukuran N untuk setiap N (tetapi perhatikan bahwa menggunakan N > 16 tidak akan meningkatkan keacakan atau mengurangi kemungkinan tabrakan):
Array(N+1).join((Math.random().toString(36)+'00000000000000000').slice(2, 18)).slice(0, N)
Penjelasan:
Pemikiran lebih lanjut:
Update:
Berikut ini adalah beberapa fungsional lainnya-gaya satu-liners yang saya datang dengan. Mereka berbeda dari solusi di atas bahwa:
Jadi, mengatakan alfabet anda pilihan
var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Kemudian kedua adalah setara dengan satu sama lain, sehingga anda dapat memilih mana yang lebih intuitif untuk anda:
Array(N).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');
dan
Array.apply(null, Array(N)).map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');
Edit:
Aku sepertinya qubyte dan Martijn de Milliano datang dengan solusi yang sama untuk yang terakhir (kudos!), yang saya tidak terjawab. Karena mereka don't terlihat pendek sekilas, aku'll meninggalkannya di sini pula dalam kasus seseorang benar-benar ingin satu-liner :-)
Juga, diganti 'Array baru' dengan 'Array' di semua solusi untuk mencukur beberapa byte.
Solusi yang paling kompak, karena slice
lebih pendek dari substring
. Mengurangkan dari akhir string memungkinkan untuk menghindari floating point simbol yang dihasilkan oleh random
fungsi:
Math.random().toString(36).slice(-5);
atau bahkan
(+new Date).toString(36).slice(-5);
Update: Menambahkan satu lebih banyak menggunakan pendekatan btoa
metode:
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));
Hal seperti ini harus bekerja
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;
}
Panggilan dengan default charset [a-zA-Z0-9] atau mengirimkan anda sendiri:
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); //A-Z
return String.fromCharCode(n + 61); //a-z
}
while (s.length < L) s += randomchar();
return s;
}
console.log(randomstring(5));
/**
* 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"
Bersenang-senang. jsBin demo
Sementara di atas menggunakan pemeriksaan tambahan yang diinginkan (A/N, A, N) output, let's memecahnya ke essentials (Alpha-Numerik hanya) untuk pemahaman yang lebih baik:
var str = "";
untuk menggabungkan karakter acakrand
nomor indeks dari 0 61** (0..9+A..Z+a..z = 62)rand
(karena itu's 0..61) incrementing dengan beberapa nomor (lihat contoh di bawah) untuk mendapatkan kembali hak CharCode
jumlah dan berkaitan dengan Karakter.str
a String.fromCharCode( bertambah rand )
Let's gambar tabel Karakter dan ranges:
_____0....9______A..........Z______a..........z___________ Character
| 10 | | 26 | | 26 | Tot = 62 characters
48....57 65..........90 97..........122 CharCode ranges
Matematika.floor( Math.random * 62 )
memberikan jangkauan dari 0..61
(apa yang kita butuhkan).
Cara untuk memperbaiki kesalahan (selisih) acak untuk mendapatkan yang benar charCode berkisar?
| 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 |
Yang bersyarat operasi logika dari tabel di atas:
rand += rand>9 ? ( rand<36 ? 55 : 61 ) : 48 ;
// rand += true ? ( true ? 55 else 61 ) else 48 ;
Jika anda mengikuti penjelasan di atas, anda harus mampu menciptakan ini alpha-numeric snippet:
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;
}
Versi yang lebih baru dengan es6 menyebar operator:
[...Array(30)].peta(() => Matematika.random().toString(36)[2]).bergabung('')
30
sewenang-wenang nomor, anda dapat memilih salah token panjang yang anda inginkan36
adalah maksimum radix nomor anda dapat lolos ke numerik.toString(), yang berarti semua angka dan a-z huruf kecil2
digunakan untuk memilih 2th nomor dari string acak yang terlihat seperti ini: "0.mfbiohx64i"
, kita bisa mengambil naik setelah 0.
Cara paling sederhana adalah:
(new Date%9e6).toString(36)
Ini menghasilkan string acak dari 5 karakter berdasarkan waktu saat ini. Contoh output adalah 4mtxj
atau 4mv90
atau 4mwp1
Masalah dengan ini adalah bahwa jika anda menyebutnya dua kali pada detik yang sama, maka akan menghasilkan string yang sama.
Cara yang lebih aman adalah:
(0|Math.random()*9e6).toString(36)
Ini akan menghasilkan string acak dari 4 atau 5 karakter, selalu berbeda. Contoh output adalah seperti 30jzm
atau 1r591
atau 4su1a
Dalam kedua cara bagian pertama menghasilkan nomor acak. The .toString(36)
bagian cor nomor base36 (alphadecimal) representasi itu.
Berikut ini adalah beberapa mudah satu liners. Perubahan new Array(5)
untuk mengatur suhu udara.
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"]();});
Aku tahu semua orang punya itu kan sudah, tapi aku merasa seperti memiliki pergi pada ini satu dari yang paling ringan cara yang mungkin(light on kode, bukan 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));
Dibutuhkan sedikit waktu untuk membungkus kepala anda sekitar, tetapi saya pikir itu benar-benar menunjukkan bagaimana awesome javascript's sintaks.
Berikut ini's metode yang saya buat.
Itu akan membuat string yang mengandung karakter huruf kecil dan besar.
Selain I've termasuk fungsi yang akan dibuat alfanumerik string juga.
Bekerja contoh:
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;
}
Upgrade juli 2015
Ini melakukan hal yang sama tapi lebih masuk akal dan termasuk semua surat-surat.
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)));
}
Dengan asumsi anda menggunakan underscorejs's mungkin untuk elegan menghasilkan string acak hanya dalam dua jalur:
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var random = _.sample(possible, 5).join('');
Dalam kasus orang yang tertarik dalam one-liner (meskipun tidak diformat seperti untuk kenyamanan anda) yang mengalokasikan memori pada saat yang sama (tetapi perhatikan bahwa untuk string kecil itu benar-benar tidak peduli) berikut adalah cara untuk melakukannya:
Array.apply(0, Array(5)).map(function() {
return (function(charset){
return charset.charAt(Math.floor(Math.random() * charset.length))
}('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'));
}).join('')
Anda dapat mengganti 5
dengan panjang dari string yang anda inginkan. Terima kasih untuk @AriyaHidayat di ini post untuk solusi untuk peta
fungsi tidak bekerja pada array jarang dibuat oleh Array(5)
.
Cepat dan meningkatkan algoritma. Tidak menjamin seragam (lihat komentar).
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;
}
Anda dapat loop melalui array dari item dan secara rekursif menambahkan mereka ke sebuah variabel string, misalnya jika anda ingin acak urutan 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));