JavaScript中的随机字母数字字符串?

在JavaScript中生成一个随机的字母数字(大写,小写和数字)字符串来用作可能唯一的标识符的最短方法是什么?

340666 次浏览

随机字符:

String.fromCharCode(i); //where is an int

随机整数:

Math.floor(Math.random()*100);

把它们放在一起:

function randomNum(hi){
return Math.floor(Math.random()*hi);
}
function randomChar(){
return String.fromCharCode(randomNum(100));
}
function randomString(length){
var str = "";
for(var i = 0; i < length; ++i){
str += randomChar();
}
return str;
}
var RandomString = randomString(32); //32 length string

小提琴:http://jsfiddle.net/maniator/QZ9J2/

如果你只想允许特定的字符,你也可以这样做:

function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

下面是一个jsfiddle来演示:http://jsfiddle.net/wSQBx/

另一种方法是使用一个特殊的字符串,告诉函数使用什么类型的字符。你可以这样做:

function randomString(length, chars) {
var mask = '';
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (chars.indexOf('#') > -1) mask += '0123456789';
if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
var result = '';
for (var i = length; i > 0; --i) result += mask[Math.floor(Math.random() * mask.length)];
return result;
}


console.log(randomString(16, 'aA'));
console.log(randomString(32, '#aA'));
console.log(randomString(64, '#A!'));

小提琴:http://jsfiddle.net/wSQBx/2/

或者,像下面描述的那样使用base36方法,你可以这样做:

function randomString(length) {
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
}

我只是发现了一个非常好的优雅的解决方案:

Math.random().toString(36).slice(2)

这个实现的注意事项:

  • 这将生成一个长度在0到12个字符之间的字符串,通常是11个字符,因为浮点字符串化删除了后面的零。
  • 它不会生成大写字母,只生成小写字母和数字。
  • 因为随机性来自Math.random(),输出可能是可预测的,因此不一定是唯一的。
  • 即使假设一个理想的实现,输出最多有52位熵,这意味着您可以在生成大约70M个字符串后期望重复。

或者根据Jar Jar的建议,这是我在最近的一个项目中使用的方法(以克服长度限制):

var randomString = function (len, bits)
{
bits = bits || 36;
var outStr = "", newStr;
while (outStr.length < len)
{
newStr = Math.random().toString(bits).slice(2);
outStr += newStr.slice(0, Math.min(newStr.length, (len - outStr.length)));
}
return outStr.toUpperCase();
};

使用:

randomString(12, 16); // 12 hexadecimal characters
randomString(200); // 200 alphanumeric characters

32个字符:

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

当我看到这个问题时,我想到了我必须生成uuid的时候。我不能把代码的功劳,因为我确信我在stackoverflow上找到了它。如果你不想在字符串中使用破折号,那就去掉破折号。函数如下:

function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid.toUpperCase();
}

小提琴:http://jsfiddle.net/nlviands/fNPvf/11227/

beans建议的另一种答案变体

(Math.random()*1e32).toString(36)

通过改变乘法器1e32你可以改变随机字符串的长度。

使用lodash:

function createRandomString(length) {
var chars = "abcdefghijklmnopqrstufwxyzABCDEFGHIJKLMNOPQRSTUFWXYZ1234567890"
var pwd = _.sampleSize(chars, length || 12)  // lodash v4: use _.sampleSize
return pwd.join("")
}
document.write(createRandomString(8))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

var randomString = function(length) {
var str = '';
var chars ='0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(
'');
var charsLen = chars.length;
if (!length) {
length = ~~(Math.random() * charsLen);
}
for (var i = 0; i < length; i++) {
str += chars[~~(Math.random() * charsLen)];
}
return str;
};

使用md5库:https://github.com/blueimp/JavaScript-MD5

最短的方法:

md5(Math.random())

如果你想限制大小为5:

md5(Math.random()).substr(0, 5)

这样更干净

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

例子

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

这个函数应该给出任意长度的随机字符串。

function randString(length) {
var l = length > 25 ? 25 : length;
var str = Math.random().toString(36).substr(2, l);
if(str.length >= length){
return str;
}
return str.concat(this.randString(length - str.length));
}

我用下面的测试成功地测试了它。

function test(){
for(var x = 0; x < 300000; x++){
if(randString(x).length != x){
throw new Error('invalid result for len ' + x);
}
}
}

之所以选择25,是因为在实践中,Math.random().toString(36).substr(2, 25)返回的字符串长度为25。这个数字可以根据您的意愿更改。

此函数是递归的,因此使用非常大的值调用该函数会导致Maximum call stack size exceeded。从我的测试中,我能够得到长度为30万字符的字符串。

通过将字符串作为第二个参数发送给函数,可以将该函数转换为尾递归。我不确定JS是否使用Tail调用优化

随机密钥生成器

keyLength参数是你想要的键的字符长度

function keyGen(keyLength) {
var i, key = "", characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";


var charactersLength = characters.length;


for (i = 0; i < keyLength; i++) {
key += characters.substr(Math.floor((Math.random() * charactersLength) + 1), 1);
}


return key;
}




keyGen(12)
"QEt9mYBiTpYD"

很好,很简单,而且不局限于一定数量的字符:

let len = 20, str = "";
while(str.length < len) str += Math.random().toString(36).substr(2);
str = str.substr(0, len);
< p >更新: 一行解决方案,随机20个字符(字母数字小写):

Array.from(Array(20), () => Math.floor(Math.random() * 36).toString(36)).join('');

或者用lodash更短:

_.times(20, () => _.random(35).toString(36)).join('');
function randomString(len) {
var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return [...Array(len)].reduce(a=>a+p[~~(Math.random()*p.length)],'');
}

简介:

  1. 创建一个我们想要的大小的数组(因为javascript中没有等价的range(len)
  2. 对于数组中的每个元素:从p中随机选择一个字符并将其添加到字符串中
  3. 返回生成的字符串。

这里做一些解释:

[...Array(len)]

Array(len)或new Array(len) 创建一个指针未定义的数组。单行语句将更难实现。传播的语法方便地定义了指针(现在它们指向未定义的对象!)

.reduce(

在本例中,减少将数组转换为单个字符串。reduce功能在大多数语言中都很常见和值得学习。

a=>a+...

我们正在使用箭头功能

a蓄电池。在这种情况下,它是我们完成时将返回的最终结果字符串(你知道它是一个字符串,因为reduce函数的第二个参数,initialValue是一个空字符串:'')。所以基本上:用p[~~(Math.random()*p.length)]转换数组中的每个元素,将结果附加到a字符串,并在完成时给我a

p[...]

p是我们要从中选择的字符串。你可以像访问索引一样访问字符串中的字符(例如,"abcdefg"[3]给了我们"d")

~~(Math.random()*p.length)

Math.random()返回一个介于[0,1)Math.floor(Math.random()*max) 在javascript中获得随机整数的事实标准吗之间的浮点数。~是javascript中按位的NOT操作符。 ~~Math.floor( 这里有一些信息

的一种更短,可以说有时更快,而且肯定更有趣的说法

我认为以下是允许给定长度的最简单的解决方案:

Array(myLength).fill(0).map(x => Math.random().toString(36).charAt(2)).join('')

这取决于箭头函数的语法。

这是一个简单的代码来生成随机字符串字母。 看看这段代码是如何工作的。

go(lenthOfStringToPrint); -使用此函数生成最终字符串
var letters = {
1: ["q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m"],
2: ["Q","W","E","R","T","Y","U","I","O","P","A","S","D","F","G","H","J","K","L","Z","X","C","V","B","N","M"]
},i,letter,final="";
random = (max,min) => {
return Math.floor(Math.random()*(max-min+1)+min);
}
function go(length) {
final="",letter="";
for (i=1; i<=length; i++){
letter = letters[random(0,3)][random(0,25)];
final+=letter;
}
return final;
}

可以直接使用lodash uniqueId:

    _.uniqueId([prefix=''])

生成唯一的ID。如果给出了prefix,则ID被追加到它后面。

一个取长度的简单函数

getRandomToken(len: number): string {
return Math.random().toString(36).substr(2, len);
}

如果你传递6,它会生成6位字母数字

我使用@Nimphious excellent 第二种方法,发现偶尔返回的字符串是数字-不是字母数字。 我使用的解决方案是测试使用!isNaN,并再次使用递归调用该函数。 何苦呢?我使用这个函数来创建对象键,如果所有的键都是字母数字,那么所有的键都可以正常排序,但如果你使用 数字作为键,与字母数字(字符串)混合循环遍历对象,将产生与原始顺序不同的顺序

function newRandomString(length, chars) {
var mask = '';
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (chars.indexOf('#') > -1) mask += '0123456789';
if (chars.indexOf('$') > -1) mask += '0123456789';


var result = '';
for (var i = length; i > 0; --i) result += mask[Math.floor(Math.random() *
mask.length)];
/*
we need a string not a number !isNaN(result)) will return true if '1234' or '3E77'
because if we're looping through object keys (created by newRandomString()) and
a number is used and all the other keys are strings then the number will
be first even if it was the 2nd or third key in object
*/
//use recursion to try again
if(!isNaN(result)){
console.log('found a number....:'+result);
return newRandomString(length, chars)
}else{
return result;
}
};


var i=0;
while (i < 1000) {
var a = newRandomString(4, '#$aA');
console.log(i+' - '+a);
//now we're using recursion this won't occur
if(!isNaN(a)){
console.log('=============='+i+' - '+a);
}
i++;
}


console.log('3E77:'+!isNaN('3E77'));//true
console.log('1234:'+!isNaN('1234'));//true
console.log('ab34:'+!isNaN('ab34'));//false