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


当前回答

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

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

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

其他回答

随机字符:

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/

我使用@Nimphious优秀的第二种方法,发现偶尔返回的字符串是数字-而不是字母数字。 我使用的解决方案是测试使用!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

32个字符:

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

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

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。这个数字可以根据您的意愿更改。

此函数是递归的,因此使用非常大的值调用函数可能会导致超过最大调用堆栈大小。从我的测试中,我能够得到长度为30万字符的字符串。

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

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

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