在JavaScript中,生成一个随机的包含字母和数字(大写、小写字母以及数字)的字符串,并将其作为可能唯一的标识符,最短的合理方法是什么?
在JavaScript中,生成一个随机的包含字母和数字(大写、小写字母以及数字)的字符串,并将其作为可能唯一的标识符,最短的合理方法是什么?
我刚刚发现这是一个非常好的优雅的解决方案:
Math.random().toString(36).slice(2)
这个实现的注意事项:
Math.random()
,输出可能是可预测的,因此不一定是唯一的。slice(2)
替代 substr(2,16)
:http://www.jacklmoore.com/notes/substring-substr-slice-javascript - Web_Designerfunction rStr() { var s=Math.random().toString(36).slice(2); return s.length===16 ? s : rStr(); }
- rescuecreative0.000001
的随机数。较小数字的toString()
类似于3.4854687E-7
,您的随机字母数字字符串将是4854687E-7
,不再是字母数字。这不符合原贴作者的要求。 - Adrian Pronkvar a = 5;a.toString(2)
;将以二进制格式返回数字5,即101
。完整文档请参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString - JAR.JAR.beans.slice(2)
中提供的数字(例如 .slice(5)
)来获得更短的字符串。 - rinogo如果您只想允许特定字符,您还可以按照以下方式进行:
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!'));
Fiddle: 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.round(Math.random() * (chars.length - 1))
将会给出比其它字符多一半的概率给[0]
和[chars.length-1]
,因为为了舍入到这些数,需要分别使用区间[0, 0.5)
和[chars.length-2+0.5, chars.length-1)
大小为0.5的数字,而其它字符需要使用大小为1的区间[index-0.5, index+0.5)
。正确的索引函数应该是:parseInt(Math.random() * chars.length)
,因为随机数函数中的上限是被排除的,并且chars.length
不会被达到:http://www.w3schools.com/jsref/jsref_random.asp - axelbrzMath.random()
永远不会返回1。它返回的值在[0,1)
之间,这意味着0包括在内,1排除在外。以下是四个不同且重要的独立来源:Mozilla:http://goo.gl/BQGZiG;Microsoft MSDN(IE):http://goo.gl/MPuCJM;w3schools:http://goo.gl/qXrK7P;Stackoverflow:http://goo.gl/CUoyIT(`num`为`1`)和http://goo.gl/D9az3C和http://goo.gl/0mERDq。你有什么依据认为1是Math.random()可能的值?因为它不是。 - axelbrz更新: 针对随机的20个字符(字母数字且为小写),提供一行解决方案:
Array.from(Array(20), () => Math.floor(Math.random() * 36).toString(36)).join('');
使用lodash可以更简短:
_.times(20, () => _.random(35).toString(36)).join('');
JAR.JAR.beans建议的另一种答案变体。
(Math.random()*1e32).toString(36)
通过更改乘数1e32
,您可以更改随机字符串的长度。
这更清洁
Math.random().toString(36).substr(2, length)
例子
Math.random().toString(36).substr(2, 5)
或者根据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
function randomString(len) {
var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return [...Array(len)].reduce(a=>a+p[~~(Math.random()*p.length)],'');
}
摘要:
- 创建所需大小的数组(因为JavaScript中没有
range(len)
的等效物)。- 对于数组中的每个元素:从
p
中选择一个随机字符并将其添加到字符串中。- 返回生成的字符串。
一些解释:
[...Array(len)]
Array(len)
或new Array(len)
会创建一个带有未定义指针的数组。单行代码可能更难实现。展开语法方便地定义了这些指针(现在它们指向未定义的对象!)。
.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('')
这取决于箭头函数的语法。
对于32个字符:
for(var c = ''; c.length < 32;) c += Math.random().toString(36).substr(2, 1)
随机字符:
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
M&I56aP=H K?<T*, ;0'9_c5Tb
- sveti petar]4INBKJ\\
_5.(/"__X,,K")]`,但有很多字符是无法使用的,并被 SO 剥离了。 - RozzA
Lodash
或Underscore
,那么请参考https://dev59.com/dnM_5IYBdhLWcg3wgja2#36734713。 - vineet