Tạo chuỗi / ký tự ngẫu nhiên trong JavaScript


1780

Tôi muốn một chuỗi 5 ký tự gồm các ký tự được chọn ngẫu nhiên từ bộ [a-zA-Z0-9].

Cách tốt nhất để làm điều này với JavaScript là gì?


48
Cảnh báo: Không có câu trả lời nào có true-randomkết quả! Họ là duy nhất pseudo-random. Khi sử dụng các chuỗi ngẫu nhiên để bảo vệ hoặc bảo mật, đừng sử dụng bất kỳ chuỗi nào !!! Hãy thử một trong những api này: Random.org
Ron van der Heijden

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

13
Vui lòng đặt giải pháp trong một giải pháp.
chryss

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

12
Lưu ý API ngẫu nhiên mã hóa web HTML5 cung cấp tính ngẫu nhiên thực sự.
mikemaccana

Câu trả lời:


2431

Tôi nghĩ rằng điều này sẽ làm việc cho bạn:

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

console.log(makeid(5));


117
Điều này tốt cho các chuỗi ngắn, nhưng hãy cẩn thận, sử dụng +=trên các chuỗi như thế này khiến nó có hành vi O (n ^ 2). Nếu bạn muốn tạo các chuỗi dài hơn, bạn nên tạo một mảng các ký tự riêng lẻ và nối chúng lại với nhau ở cuối.
dan_waterworth

97
@dan_waterworth Nó có lẽ không quan trọng trong hầu hết mọi trường hợp: codinghorror.com/blog/2009/01/...
Alex Reece

7
@dan_waterworth, Trên thực tế, +=thường nhanh hơn vì một số lý do, thậm chí được sử dụng bên trong các vòng lặp - jsperf.com/join-vs-concatenation
Konrad Borowski

18
@JonathanPaulson Cho tôi xem các con số . Xem nhận xét trước đó với liên kết jsperf hoặc jsperf.com/sad-tragedy-of-microoptimization hoặc sitepen.com/blog/2008/05/09/opes-performance-an-analysis, v.v. Ngoài ra, câu hỏi này chỉ liên quan đến 5 câu hỏi .
Alex Reece

11
@codenamejames Vui lòng không sử dụng tính năng này trong việc tạo mật khẩu. Nó chỉ là giả ngẫu nhiên không an toàn. Giả sử bạn đang sử dụng Node (Tôi thậm chí không chắc bắt đầu từ đâu nếu bạn đang muối mặt phía khách hàng), cryptothay vào đó hãy sử dụng .
Thủy nhiệt

2330

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

Lưu ý: Thuật toán trên có các điểm yếu sau:

  • Nó sẽ tạo ra bất cứ nơi nào từ 0 đến 6 ký tự do thực tế là các số 0 ở cuối bị xóa khi xâu chuỗi các dấu phẩy động.
  • Nó phụ thuộc sâu vào thuật toán được sử dụng để xâu chuỗi các số dấu phẩy động, rất phức tạp. (Xem bài viết "Cách in số dấu phẩy động chính xác" .)
  • Math.random()có thể tạo ra đầu ra ("tìm kiếm ngẫu nhiên" nhưng không thực sự ngẫu nhiên) tùy thuộc vào việc thực hiện. Chuỗi kết quả không phù hợp khi bạn cần đảm bảo tính duy nhất hoặc không thể đoán trước.
  • Ngay cả khi nó tạo ra 6 ký tự ngẫu nhiên, không thể đoán trước, bạn có thể thấy một bản sao sau khi chỉ tạo khoảng 50.000 chuỗi, do nghịch lý sinh nhật . (sqrt (36 ^ 6) = 46656)

276
Math.random().toString(36).substr(2, 5), vì .substring(7)làm cho nó dài hơn 5 ký tự. Điểm đầy đủ, vẫn còn!
rồng

81
@Scoop toStringPhương thức của một loại số trong javascript có một tham số tùy chọn để chuyển đổi số thành một cơ sở nhất định. Ví dụ, nếu bạn vượt qua hai, bạn sẽ thấy số của mình được thể hiện dưới dạng nhị phân. Tương tự như hex (cơ sở 16), cơ sở 36 sử dụng các chữ cái để biểu thị các chữ số ngoài 9. Bằng cách chuyển đổi một số ngẫu nhiên thành cơ sở 36, bạn sẽ kết thúc với một loạt các chữ cái và số dường như ngẫu nhiên.
Chris Baker

76
Nhìn đẹp nhưng trong vài trường hợp, điều này tạo ra chuỗi rỗng! Nếu ngẫu nhiên trả về 0, 0,5, 0,25, 0,125 ... sẽ dẫn đến chuỗi rỗng hoặc ngắn.
gertas

67
@gertas Điều này có thể tránh được(Math.random() + 1).toString(36).substring(7);
George Reith

84
Guy, điều này là gần như vô dụng. Chạy nó chỉ 1000000 lần và bạn thường nhận được khoảng 110000 lần lặp lại: var value = {}, i = 0, trùng lặpCount = 0, val; while (i <1000000) {val = Math.random (). toString (36) .sub chuỗi (7); if (giá trị [val]) {trùng lặpCount ++; } giá trị [val] = 1; i ++; } console.log ("TOTAL DUPLICATE", trùng lặp);
hacklikecrack

463

Math.random là xấu cho loại điều này

lựa chọn 1

Nếu bạn có thể thực hiện phía máy chủ này , chỉ cần sử dụng mô-đun mật mã -

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

// "bb5dc8842ca31d4603d6aa11448d1654"

Chuỗi kết quả sẽ dài gấp đôi số byte ngẫu nhiên mà bạn tạo ra; mỗi byte được mã hóa thành hex là 2 ký tự. 20 byte sẽ là 40 ký tự hex.


Lựa chọn 2

Nếu bạn phải thực hiện ứng dụng khách này , có thể thử mô-đun uuid -

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

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

Lựa chọn 3

Nếu bạn phải thực hiện ứng dụng khách này và bạn không phải hỗ trợ các trình duyệt cũ, bạn có thể làm điều đó mà không cần phụ thuộc -

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


Để biết thêm thông tin về crypto.getRandomValues-

Các crypto.getRandomValues()phương pháp cho phép bạn nhận được các giá trị ngẫu nhiên mã hóa mạnh mẽ. Mảng được đưa ra dưới dạng tham số chứa đầy các số ngẫu nhiên (ngẫu nhiên theo nghĩa mật mã của nó).

Đây là một ví dụ giao diện điều khiển nhỏ -

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

Để hỗ trợ IE11 bạn có thể sử dụng -

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

Để biết phạm vi trình duyệt, hãy xem https://caniuse.com/#feat=getrandomvalues


4
Chính xác. Mặc dù UUID là tốt để gán ID cho một vật, sử dụng nó như một chuỗi các ký tự ngẫu nhiên không phải là ý tưởng tuyệt vời cho lý do này (và có thể là khác).
wmassingham

2
Không cần .map()trong Tùy chọn 3. Array.from(arr, dec2hex).join('')=== Array.from(arr).map(dec2hex).join(''). Cảm ơn đã giới thiệu cho tôi các tính năng này :-)
Fred Gandt

6
Bạn nên đề cập trong câu trả lời rằng tùy chọn 2 cũng cần node.js để hoạt động, đó không phải là javascript thuần túy.
Esko

5
Mặc dù an toàn hơn về mặt mật mã, nhưng điều này thực sự không thỏa mãn các yêu cầu của câu hỏi vì nó chỉ xuất ra 0-9 và af (Hệ thập lục phân), chứ không phải 0-9, az, AZ.
qJake

1
Không phải requiremô-đun chỉ có thể được sử dụng phía máy chủ?
aJetHorn 18/2/19

173

Ngắn gọn, dễ dàng và đáng tin cậy

Trả về chính xác 5 ký tự ngẫu nhiên, trái ngược với một số câu trả lời được xếp hạng hàng đầu được tìm thấy ở đây.

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

9
Nếu Math.random().toString(36)trả về một số có ít hơn 5 ký tự thì sao?
Michael Litvin

3
Chà, đó là một bản cáo trạng thú vị từ @ Aperçu, tôi không nói rằng tôi đã phát minh ra giải pháp nhưng tôi đã sử dụng nó trong các dự án của tôi trong nhiều năm nay. Và nó không có gì để làm với bình luận mà bạn đề cập. Và tôi khá chắc chắn rằng trong SO, điều quan trọng là thông tin hữu ích nhất ở đúng nơi và ngay cả khi nó đã tồn tại ở một nơi khác. May mắn thay, có vẻ như ít nhất 51 chàng trai đã tìm thấy câu trả lời này hữu ích, xin chào mừng bạn!
Nhẫn bạc ngày

3
Để tránh nhận chuỗi rỗng trong trường hợp Math.random () trả về 0, bạn có thể sử dụngfunction getRandomString() { var result = ''; while (!result) result = Math.random().toString(36).substring(2); return result; };
mikep

5
@rinogo Math.random () có thể trả về 0 nhưng không phải là 1 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
trộm

6
Tôi đã chạy mã này 1.000.000.000 lần và vẫn không nhận được chuỗi trống: jsfiddle.net/mtp5730r Tôi sẽ nói rằng bạn khá an toàn khi nhận được chuỗi trống.
Macroman

157

Đây là một cải tiến về câu trả lời tuyệt vời của mystletap . Bản gốc có hai nhược điểm được giải quyết ở đây:

Đầu tiên, như những người khác đã đề cập, nó có xác suất nhỏ tạo ra các chuỗi ngắn hoặc thậm chí là một chuỗi trống (nếu số ngẫu nhiên là 0), có thể phá vỡ ứng dụng của bạn. Đây là một giải pháp:

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

Thứ hai, cả bản gốc và giải pháp trên đều giới hạn kích thước chuỗi N đến 16 ký tự. Sau đây sẽ trả về một chuỗi kích thước N cho bất kỳ N (nhưng lưu ý rằng sử dụng N> 16 sẽ không làm tăng tính ngẫu nhiên hoặc giảm xác suất va chạm):

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

Giải trình:

  1. Chọn một số ngẫu nhiên trong phạm vi [0,1), tức là từ 0 (đã bao gồm) và 1 (độc quyền).
  2. Chuyển đổi số thành chuỗi cơ sở-36, tức là sử dụng các ký tự 0-9 và az.
  3. Pad với số không (giải quyết vấn đề đầu tiên).
  4. Lát ra khỏi hàng đầu '0.' tiền tố và số không đệm thêm.
  5. Lặp lại chuỗi đủ số lần để có ít nhất N ký tự trong đó (bằng cách nối các chuỗi trống với chuỗi ngẫu nhiên ngắn hơn được sử dụng làm dấu phân cách).
  6. Cắt chính xác N ký tự từ chuỗi.

Suy nghĩ thêm:

  • Giải pháp này không sử dụng chữ in hoa, nhưng trong hầu hết các trường hợp (không có ý định chơi chữ) nó không thành vấn đề.
  • Độ dài chuỗi tối đa tại N = 16 trong câu trả lời ban đầu được đo bằng Chrome. Trong Firefox, N = 11. Nhưng như đã giải thích, giải pháp thứ hai là về việc hỗ trợ bất kỳ độ dài chuỗi được yêu cầu nào, không phải về việc thêm tính ngẫu nhiên, vì vậy nó không tạo ra nhiều sự khác biệt.
  • Tất cả các chuỗi trả về có xác suất được trả về bằng nhau, ít nhất là cho đến khi kết quả mà Math.random () trả về được phân bổ đều (trong trường hợp này không phải là ngẫu nhiên về cường độ mã hóa, trong mọi trường hợp).
  • Không phải tất cả các chuỗi có thể có kích thước N có thể được trả về. Trong giải pháp thứ hai, điều này là hiển nhiên (vì chuỗi nhỏ hơn chỉ đơn giản là được sao chép), nhưng trong câu trả lời ban đầu, điều này là đúng vì trong quá trình chuyển đổi sang cơ sở-36, một số bit cuối cùng có thể không phải là một phần của các bit ngẫu nhiên ban đầu. Cụ thể, nếu bạn nhìn vào kết quả của Math.random (). ToString (36), bạn sẽ nhận thấy ký tự cuối cùng không được phân phối đều. Một lần nữa, trong hầu hết các trường hợp, điều đó không thành vấn đề, nhưng chúng tôi cắt chuỗi cuối cùng từ đầu thay vì kết thúc chuỗi ngẫu nhiên để các chuỗi ngắn (ví dụ N = 1) không bị ảnh hưởng.

Cập nhật:

Dưới đây là một vài loại lót khác theo phong cách chức năng mà tôi nghĩ ra. Chúng khác với giải pháp ở trên:

  • Họ sử dụng một bảng chữ cái tùy ý rõ ràng (chung chung hơn và phù hợp với câu hỏi ban đầu yêu cầu cả chữ hoa và chữ thường).
  • Tất cả các chuỗi có độ dài N có xác suất được trả về bằng nhau (nghĩa là các chuỗi không chứa sự lặp lại).
  • Chúng dựa trên một chức năng bản đồ, chứ không phải là mẹo toString (36), giúp chúng trở nên đơn giản và dễ hiểu hơn.

Vì vậy, giả sử bảng chữ cái của bạn là

var s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

Sau đó, hai cái này tương đương với nhau, vì vậy bạn có thể chọn bất cứ thứ gì trực quan hơn với bạn:

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

Biên tập:

Tôi có vẻ như qubyteMartijn de Milliano đã đưa ra các giải pháp tương tự như sau này (kudos!), Mà bằng cách nào đó tôi đã bỏ lỡ. Vì chúng không nhìn thoáng qua, dù sao tôi cũng sẽ để nó ở đây trong trường hợp ai đó thực sự muốn có một lớp lót :-)

Ngoài ra, thay thế 'Mảng mới' bằng 'Mảng' trong tất cả các giải pháp để loại bỏ thêm một vài byte.


Tại sao không chỉ thêm 1? (Math.random()+1).toString(36).substring(7);
emix

Bởi vì thêm 1 không giải quyết được một trong hai vấn đề được thảo luận ở đây. Ví dụ: (1) .toString (36) .sub chuỗi (7) tạo ra một chuỗi rỗng.
amichair

Việc sử dụng Math.random().toString(36).substring(2,7)mang lại một kết quả mong đợi giống như.substring(2, n+2)
Joseph Rex

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

Điều này thật tuyệt, nhưng khi được thực thi trong Firefox với N = 16, ~ 6 chữ số cuối cùng kết thúc bằng 0 ... (Nhưng nó đáp ứng mong muốn của OP về 5 ký tự ngẫu nhiên.)
Edward Newell

128

Giải pháp nhỏ gọn nhất, vì slicengắn hơn substring. Phép trừ từ cuối chuỗi cho phép tránh ký hiệu dấu phẩy động được tạo bởi randomhàm:

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

hoặc thậm chí

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

Cập nhật: Đã thêm một cách tiếp cận bằng btoaphương pháp:

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

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

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

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

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


Math.random().toString(36).slice(-5); - Chuyện gì xảy ra nếu Math.random() trở về 0.0thì sao?
X-quang

@ x-quang, bạn sẽ nhận được "0";)
Valentin Podkamennyi

2
Chính xác. ;) Và nếu Math.random()trả về 0.5kết quả là "0.i". Không chắc chắn nếu có trường hợp cạnh khác. Chỉ muốn chỉ ra rằng đây không phải là một câu trả lời chính xác cho câu hỏi (5 ký tự từ [a-zA-Z0-9]).
X-quang

2
@ x-ray, tôi sẽ không nói rằng đây là câu trả lời đúng, tôi chỉ nói rằng đây là phiên bản rút gọn của câu trả lời @doubletap ở trên. Cá nhân tôi sử dụng (+new Date + Math.random())để ngăn chặn trường hợp này. Dù sao, cảm ơn bạn đã lưu ý.
Valentin Podkamennyi

1
Điều này. Tôi không biết tại sao các câu trả lời khác yêu cầu rất nhiều mã
john ktejik

100

Một cái gì đó như thế này sẽ làm việc

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

Gọi với bộ ký tự mặc định [a-zA-Z0-9] hoặc tự gửi:

var randomValue = randomString(5);

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

Một biến thể của ví dụ ở đây có thể được tìm thấy ở đây: mediacolitic.com/iNET/javascript/number/random.html
David

1
cũng có thể chỉ giảm lentrực tiếp trong một whilevòng lặp
drzaus

Cảm ơn, tôi vừa đăng bên dưới một biến thể coffeescript của ví dụ này: stackoverflow.com/a/26682781/262379
Dinis Cruz

Nếu những thứ này sẽ được sử dụng công khai, thì có lẽ bạn nên loại bỏ các nguyên âm. Ít entropy hơn, nhưng an toàn hơn rất nhiều vì bạn không thể tạo ra bất kỳ từ nào có thể xúc phạm mọi người. Đó là lý do tại sao tôi thích điều này, vì tôi có thể gửi chuỗi ký tự của riêng mình. Làm tốt lắm.
Nate Bunney

Khá khó, làm việc cho tôi, Cảm ơn!
Zaki Mohammed

73

Một phiên bản mới hơn với toán tử lây lan es6 :

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

  • Số 30tùy ý, bạn có thể chọn bất kỳ độ dài mã thông báo nào bạn muốn
  • Số 36cơ số tối đa bạn có thể chuyển cho num.toString () , có nghĩa là tất cả các số và chữ cái viết thường az
  • Các 2được sử dụng để chọn chỉ số thứ 3 từ chuỗi ngẫu nhiên mà trông như thế này: "0.mfbiohx64i"chúng ta có thể lấy bất kỳ chỉ số sau0.

Bạn có thể giải thích? Đặc biệt là tại sao bạn chuyển 36 đến toString () và tại sao bạn chọn phần tử thứ 3?
vuza

5
đây là giải pháp tốt nhất
overcomer

hay, nhưng giải pháp này không bao gồm các ký tự [AZ] như câu hỏi được yêu cầu, chỉ [a-z0-9]
Nahuel Greco

71

function randomstring(L) {
  var s = '';
  var randomchar = function() {
    var n = Math.floor(Math.random() * 62);
    if (n < 10) return n; //1-10
    if (n < 36) return String.fromCharCode(n + 55); //A-Z
    return String.fromCharCode(n + 61); //a-z
  }
  while (s.length < L) s += randomchar();
  return s;
}
console.log(randomstring(5));


Tôi thích điều này nhất. Bạn có thể dễ dàng sửa đổi để chấp nhận các tham số bổ sung và chỉ trả về số, mức thấp hoặc giới hạn. Tôi không nghĩ phong cách siêu nén là cần thiếtwhile(s.length< L) s+= randomchar();
mastaBlasta

3
Cũng while(L--)sẽ làm điều đó
vsync

1
Tốt hơn là sử dụng số mạnh 'A'.charCodeAt(0)hơn là số ma thuật 55(và tương tự cho số 61). Đặc biệt là, trên nền tảng của tôi, con số ma thuật trả về là 65. Mã đó sẽ tự tài liệu tốt hơn là tốt.
Grumdrig

Tôi đã tạo một biến thể tối ưu hóa tối thiểu hóa (nhỏ hơn 46 byte) cho việc triển khai của bạn tại đây: stackoverflow.com/a/52412162
Waruyama

Chúc may mắn bao giờ gỡ lỗi mà @Waruyama. Đó là những gì webpack là dành cho!
Dylan Watson

61

Trình tạo chuỗi ngẫu nhiên (Alpha-Numeric | Alpha | Numeric)

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

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


Mặc dù ở trên sử dụng các kiểm tra bổ sung cho đầu ra A / N, A, N mong muốn , chúng ta hãy chia nhỏ nó thành các yếu tố cần thiết (chỉ Alpha-Numeric) để hiểu rõ hơn:

  • Tạo một hàm chấp nhận một đối số (độ dài mong muốn của kết quả Chuỗi ngẫu nhiên)
  • Tạo một chuỗi rỗng như var str = "";để ghép các ký tự ngẫu nhiên
  • Bên trong một vòng lặp tạo một randsố chỉ mục từ 0 đến 61 (0..9 + A..Z + a..z = 62)
  • Tạo một logic có điều kiện để Điều chỉnh / sửa chữarand (vì nó bằng 0..61) tăng nó theo một số (xem ví dụ bên dưới) để lấy lại đúng CharCodesố và Ký tự liên quan.
  • Bên trong vòng lặp nối với strmộtString.fromCharCode( incremented rand )

Hãy hình dung phạm vi bảng ký tự 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 )đưa ra một phạm vi từ 0..61(những gì chúng ta cần).
Chúng ta hãy sửa ngẫu nhiên để có được phạm vi charCode chính xác :

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

Các hoạt động có điều kiện luận lý từ bảng trên:

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

Từ lời giải thích ở trên, đây là đoạn trích kết quả số-chữ :

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

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

Hoặc nếu bạn sẽ:

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

console.log(randomString(10))


33

Cách đơn giản nhất là:

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

Điều này tạo ra chuỗi ngẫu nhiên gồm 5 ký tự dựa trên thời gian hiện tại. Ví dụ đầu ra là 4mtxjhay 4mv90hay4mwp1

Vấn đề với điều này là nếu bạn gọi nó hai lần trên cùng một giây, nó sẽ tạo ra cùng một chuỗi.

Cách an toàn hơn là:

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

Điều này sẽ tạo ra một chuỗi ngẫu nhiên gồm 4 hoặc 5 ký tự, luôn luôn khác nhau. Ví dụ đầu ra cũng giống như 30jzmhoặc 1r591hoặc4su1a

Trong cả hai cách, phần đầu tiên tạo ra một số ngẫu nhiên. Phần này .toString(36)đúc số cho một đại diện cơ sở36 (bảng chữ cái) của nó.


Tôi không chắc chắn làm thế nào điều này trả lời câu hỏi; Đây là một câu hỏi 7 năm tuổi với nhiều câu trả lời hợp lệ. Nếu bạn chọn cung cấp một câu trả lời mới, bạn thực sự cần hết sức cẩn thận để đảm bảo rằng câu trả lời của bạn được giải thích rõ ràng và được ghi lại.
Claies 11/03/2015

1
Nếu bạn sử dụng Date, tại sao bạn không sử dụng nó như sau:(+new Date).toString(36)
Seniorpreacher

Tôi thích giải pháp số ngẫu nhiên của bạn nhưng 9e6 chỉ cung cấp 9 triệu khả năng trong số 60,4 triệu số cho 5 chữ số (36 ^ 5) để bạn có thể thay thế bằng (0|Math.random()*6.04e7).toString(36)để che nó.
Le Droid

1
Tôi muốn một chuỗi ngẫu nhiên dài với một thói quen ngắn nhất có thể (đối với bản demo mã) mà không cần phải tuyệt vời về mặt mật mã, chỉ cần tạo ra một số "lông tơ" ngẫu nhiên trực quan đẹp. Tôi thích câu trả lời này tốt nhất (thứ 2 của bạn), vì vậy cảm ơn bạn. Hai xu của tôi: Tôi có thể đánh bại nó trong thời gian ngắn với một lần gõ phím ít hơn và nó thường sẽ tạo ra 13 ký tự ngẫu nhiên (không có dấu chấm) : (Math.random()*1e20).toString(36).
Andrew Willems

Một điều tôi có với câu trả lời này là nó sẽ không sử dụng [AZ] mà xảy ra trong câu hỏi ban đầu.
user.friendly

22

Dưới đây là một số lót dễ dàng. Thay đổi new Array(5)để đặt độ dài.

Kể cả 0-9a-z

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

Kể cả 0-9a-zA-Z

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

20

Tôi biết tất cả mọi người đã có nó ngay, nhưng tôi cảm thấy muốn đi đến cái này theo cách nhẹ nhất có thể (nhẹ về mã, không phải 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));

Phải mất một chút thời gian để quấn đầu bạn, nhưng tôi nghĩ nó thực sự cho thấy cú pháp của javascript tuyệt vời như thế nào.


20
Nếu bạn đang cố giữ mã ngắn, tại sao lại viết current = current ? current : '';khi bạn có thể viết current = current || '';
CaffGeek

9
vì chúng ta đang nói về tối ưu hóa vi mô ở đây nên tôi thực sự sẽ đề nghị bỏ qua việc gán biến hoàn toàn nếu không cần thiết:current || (current = '');
Thomas Heymann

Cố gắng tối ưu hóa vi mô trong khi sử dụng thuật toán đệ quy "đẹp" nhưng lãng phí tài nguyên sẽ không có ý nghĩa :-) Một vòng lặp vẫn là tốt nhất trong Javascript và đánh bại đệ quy thời gian lớn, cho đến khi những tiến bộ thực sự lớn trong mã tối ưu hóa của thời gian chạy được thực hiện.
Mörre

17

Nếu bạn đang sử dụng Lodash hoặc Underscore , thì thật đơn giản:

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

6
Sử dụng Lodash_.sampleSize('asdfgh',5).join('')
Marlo

2
Đây thực sự không phải là một giải pháp tốt, bởi vì mỗi tài liệu mỗi nhân vật là từ một chỉ mục duy nhất. Điều đó có nghĩa là nó không thực sự ngẫu nhiên, vì không nhân vật nào có thể / sẽ lặp lại.
Random_user_name

16

Để đáp ứng yêu cầu [a-zA-Z0-9] và độ dài = 5 sử dụng

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

Chữ thường, chữ in hoa và số sẽ xảy ra.


1
Tôi đoán, Math.random () có thể dẫn đến một chuỗi base64 với quá ít ký tự.
Leif

14

Trong trường hợp bất cứ ai quan tâm đến một lớp lót (mặc dù không được định dạng như vậy để thuận tiện cho bạn) phân bổ bộ nhớ cùng một lúc (nhưng lưu ý rằng đối với các chuỗi nhỏ, điều đó thực sự không quan trọng) ở đây là cách thực hiện:

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

Bạn có thể thay thế 5bằng độ dài của chuỗi bạn muốn. Cảm ơn @AriyaHidayat trong bài đăng này cho giải pháp cho mapchức năng không hoạt động trên mảng thưa thớt được tạo bởi Array(5).


13
Mỗi chương trình javascript là 'một lớp' nếu bạn định dạng như vậy
hacklikecrack

13

Đây là phương pháp tôi đã tạo.
Nó sẽ tạo ra một chuỗi chứa cả ký tự chữ hoa và chữ thường.
Ngoài ra, tôi đã bao gồm chức năng sẽ tạo ra một chuỗi ký tự chữ và số.

Ví dụ hoạt động:
http://jsfiddle.net/greatbigmassive/vhsxs/ (chỉ alpha)
http://jsfiddle.net/greatbigmassive/PJwg8/ (chữ và số)

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

Nâng cấp tháng 7 năm 2015
Điều này làm điều tương tự nhưng có ý nghĩa hơn và bao gồm tất cả các chữ cái.

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

Với chức năng này, bạn không bao giờ có thể nhận được một chữ cái viết hoa lớn hơn 'M' hoặc một chữ cái viết thường nhỏ hơn 'n'.
erkanyildiz

Có thật không? Ồ! có lẽ sẽ kiểm tra nó nhiều hơn sau đó Tuy nhiên, Hmm, do đó là một chuỗi ngẫu nhiên và chúng tôi không thực sự quan tâm những chữ cái nào trong đó (miễn là chúng là ngẫu nhiên), nhưng nó vẫn làm những gì chúng tôi muốn nó là điều quan trọng nhưng có, sẽ cung cấp một nâng cấp, cảm ơn.
Adam

12

Giả sử bạn sử dụng dấu gạch dưới , có thể tạo chuỗi ngẫu nhiên một cách tao nhã chỉ trong hai dòng:

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

6
Điều này sẽ làm cho giá trị trả về có tất cả các ký tự duy nhất. Ngoài ra, độ dài của chuỗi được giới hạn đến độ dài của var có thể.
Yefu

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

Giải pháp đơn giản, sạch sẽ
Mark Swardstrom

Điều này xứng đáng với +1 lớn hơn
Walid Ammar

10

Thuật toán nhanh và cải tiến. Không đảm bảo đồng phục (xem bình luận).

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

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let array;

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

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

    let result = '';

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

    return result;
}

2
Câu trả lời tuyệt vời, nhưng xác suất không đồng nhất. Có 62 ký tự có thể và crypto.getRandomValuestrả về một trong 256 giá trị duy nhất. Vì 256 không được chia cho 62, nên cuối cùng bạn có xác suất nhận được ký tự AH cao hơn một chút. Tôi nghĩ giải pháp tốt nhất là làm những gì YouTube đã làm và chỉ cần thêm 2 ký tự (có thể -_) vào bộ ký tự. Dù sao, công việc tuyệt vời - câu trả lời này cần rất nhiều tình yêu hơn :)
TeWu

thêm - và _ là một ý tưởng tuyệt vời vì nó sẽ giúp bạn hoàn thành bộ cơ sở an toàn
url64

8

Vấn đề với các câu trả lời cho câu hỏi "Tôi cần chuỗi ngẫu nhiên" (bằng bất kỳ ngôn ngữ nào) thực tế là mọi giải pháp đều sử dụng một đặc tả chính thiếu sót về độ dài chuỗi . Các câu hỏi hiếm khi tiết lộ lý do tại sao các chuỗi ngẫu nhiên là cần thiết, nhưng tôi sẽ thách thức bạn hiếm khi cần các chuỗi có độ dài ngẫu nhiên, nói 8. Điều bạn luôn cần là một số chuỗi duy nhất , ví dụ, để sử dụng làm định danh cho mục đích nào đó.

Có hai cách hàng đầu để có được các chuỗi duy nhất nghiêm ngặt : xác định (không phải là ngẫu nhiên) và lưu trữ / so sánh (đó là rất khó). Chúng ta làm gì? Chúng tôi từ bỏ con ma. Chúng tôi đi với sự độc đáo xác suất thay thế. Đó là, chúng tôi chấp nhận rằng có một số rủi ro (dù nhỏ) rằng chuỗi của chúng tôi sẽ không phải là duy nhất. Đây là nơi hiểu xác suất va chạmentropy là hữu ích.

Vì vậy, tôi sẽ định nghĩa lại nhu cầu bất biến là cần một số chuỗi có rủi ro lặp lại nhỏ. Ví dụ cụ thể, giả sử bạn muốn tạo tiềm năng 5 triệu ID. Bạn không muốn lưu trữ và so sánh từng chuỗi mới và bạn muốn chúng là ngẫu nhiên, vì vậy bạn chấp nhận một số rủi ro lặp lại. Ví dụ: giả sử rủi ro ít hơn 1 trong một nghìn tỷ cơ hội lặp lại. Vậy bạn cần độ dài của chuỗi? Vâng, câu hỏi đó không được xác định rõ vì nó phụ thuộc vào các ký tự được sử dụng. Nhưng quan trọng hơn, đó là sai lầm. Những gì bạn cần là một đặc điểm kỹ thuật của entropy của chuỗi, không phải độ dài của chúng. Entropy có thể liên quan trực tiếp đến xác suất lặp lại trong một số chuỗi. Độ dài chuỗi không thể.

Và đây là nơi mà một thư viện như EntropyString có thể giúp đỡ. Để tạo ID ngẫu nhiên có ít hơn 1 trong một nghìn tỷ cơ hội lặp lại trong 5 triệu chuỗi bằng cách sử dụng entropy-string:

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

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

const string = random.string(bits)

"44hTNghjNHGGRHqH9"

entropy-stringsử dụng một bộ ký tự với 32 ký tự theo mặc định. Có các bộ ký tự được xác định trước khác và bạn cũng có thể chỉ định các ký tự của riêng mình. Ví dụ: tạo ID có cùng entropy như trên nhưng sử dụng các ký tự hex:

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

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

const string = random.string(bits)

"27b33372ade513715481f"

Lưu ý sự khác biệt về độ dài chuỗi do sự khác biệt về tổng số ký tự trong bộ ký tự được sử dụng. Nguy cơ lặp lại trong số chuỗi tiềm năng được chỉ định là như nhau. Độ dài chuỗi không. Và tốt nhất, nguy cơ lặp lại và số chuỗi tiềm năng là rõ ràng. Không còn phải đoán với độ dài chuỗi.


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

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

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

    return result.join('');
}

Điều này là sạch như nó sẽ nhận được. Nó cũng nhanh, http://jsperf.com/ay-random-opes .


Đối với tôi, điều này luôn tạo ra các chuỗi ngẫu nhiên với strLength - 1: - /
xanderiel

3
Chuyển từ --strLengthđể strLength--sửa nó cho tôi.
xanderiel

7

Bạn có thể lặp qua một mảng các mục và thêm đệ quy chúng vào một biến chuỗi, ví dụ nếu bạn muốn một chuỗi DNA ngẫu nhiên:

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

console.log(randomDNA(5));


6

Tôi không tìm thấy một giải pháp sạch để hỗ trợ cả ký tự chữ thường và chữ hoa.

Chữ thường chỉ hỗ trợ:

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

Dựa trên giải pháp đó để hỗ trợ chữ thường và chữ hoa:

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

Thay đổi 5trong substr(2, 5)để điều chỉnh độ dài bạn cần.


6

Lót:

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

Để làm cho nó ngắn hơn thay đổi đối số trong Array(15)một giá trị nhỏ hơn. Vd : Array(4).
Andrew

Tôi thực sự thích giải pháp này, đơn giản và rõ ràng. Nó đang tạo ra 15 số ngẫu nhiên trong khoảng từ 0 đến 1, tạo ra hệ thập lục phân và sau đó loại bỏ hai ký tự đầu tiên. Cuối cùng, nó là hợp nhất tất cả chúng lại với nhau.
Siscia

5

Điều này chắc chắn hoạt động

<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

Làm thế nào về một cái gì đó như thế này: Date.now().toString(36) Không phải là rất ngẫu nhiên, nhưng ngắn và khá độc đáo mỗi khi bạn gọi nó.


1
Thật không may, điều này sẽ không phải là duy nhất, vì Date.now()chỉ có độ phân giải mili giây. Khi chạy trong một vòng lặp đơn giản, chẳng hạn, bạn sẽ nhận được rất nhiều bản sao. for (let i = 0; i < 10; ++i) { console.log(Date.now().toString(36)); }.
Nate

5

Trường hợp ký tự chữ và số không nhạy:

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

Lợi ích của hàm này là bạn có thể nhận được chuỗi ngẫu nhiên có độ dài khác nhau và nó đảm bảo độ dài của chuỗi.

Trường hợp nhạy cảm Tất cả các ký tự:

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

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

Chars tùy chỉnh

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


Câu trả lời này phù hợp hơn cho trường hợp sử dụng của tôi. Sẽ thật tuyệt nếu bạn có thể thêm một lượt var possiblethích trong câu trả lời được chấp nhận, vì vậy kết quả của chức năng sẽ có cấu hình hơn.
Denis.Sabolotni

4

Tạo chuỗi dài 10 ký tự. Độ dài được đặt theo tham số (mặc định 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

Bạn có thể sử dụng coderain . Đó là một thư viện để tạo mã ngẫu nhiên theo mẫu đã cho. Sử dụng #như một trình giữ chỗ cho các ký tự viết hoa và viết thường cũng như các chữ số:

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

Có những chỗ Adành sẵn khác như cho chữ in hoa hoặc 9cho chữ số.

Điều có thể hữu ích là gọi .next() sẽ luôn mang lại cho bạn một kết quả duy nhất để bạn không phải lo lắng về các bản sao.

Dưới đây là một ứng dụng demo tạo ra một danh sách các mã ngẫu nhiên duy nhất .

Tiết lộ đầy đủ: Tôi là tác giả của coderain.


KHÔNG KHÔNG KHÔNG - sử dụng các phương pháp bản địa.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.