我想生成一个随机字符串,必须有来自az和3个数字的5个字母.
我怎么能用javascript做到这一点?
我有以下脚本,但它不符合我的要求.
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
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);
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*b W 285
强制使用固定数量的字符是一个坏主意.它不会提高密码的质量.更糟糕的是,它减少了可能的密码数量,因此通过强制进行黑客攻击变得更容易.
要生成由字母数字字符组成的随机单词,请使用:
var randomstring = Math.random().toString(36).slice(-8);
Run Code Online (Sandbox Code Playgroud)
Math.random() // Generate random number, eg: 0.123456
.toString(36) // Convert to base-36 : "0.4fzyo82mvyr"
.slice(-8);// Cut off last 8 characters : "yo82mvyr"
Run Code Online (Sandbox Code Playgroud)
Number.prototype.toString和string.prototype.slice方法的文档.
saa*_*aaj 36
更加可维护和安全的方法.
var Password = {
_pattern : /[a-zA-Z0-9_\-\+\.]/,
_getRandomByte : function()
{
// http://caniuse.com/#feat=getrandomvalues
if(window.crypto && window.crypto.getRandomValues)
{
var result = new Uint8Array(1);
window.crypto.getRandomValues(result);
return result[0];
}
else if(window.msCrypto && window.msCrypto.getRandomValues)
{
var result = new Uint8Array(1);
window.msCrypto.getRandomValues(result);
return result[0];
}
else
{
return Math.floor(Math.random() * 256);
}
},
generate : function(length)
{
return Array.apply(null, {'length': length})
.map(function()
{
var result;
while(true)
{
result = String.fromCharCode(this._getRandomByte());
if(this._pattern.test(result))
{
return result;
}
}
}, this)
.join('');
}
};Run Code Online (Sandbox Code Playgroud)
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>Run Code Online (Sandbox Code Playgroud)
mwa*_*wag 22
许多答案(包括本文的原文)都没有解决OP的字母和数字计数要求.以下是两种解决方案:一般(无最小字母/数字)和规则.
我相信这是比上述更好的一般解决方案,因为:
注意
三内胆:
var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var pwdLen = 10;
var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');
Run Code Online (Sandbox Code Playgroud)
或者,作为一个班轮:
var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');
Run Code Online (Sandbox Code Playgroud)
现在,上面的变化.这将从给定的字符集生成三个随机字符串(字母,数字,或者),然后对结果进行加扰.
请注意,以下使用sort()仅用于说明目的.对于生产用途,请使用诸如Durstenfeld之类的shuffle函数替换下面的sort()函数.
首先,作为一个功能:
function randPassword(letters, numbers, either) {
var chars = [
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", // letters
"0123456789", // numbers
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" // either
];
return [letters, numbers, either].map(function(len, i) {
return Array(len).fill(chars[i]).map(function(x) {
return x[Math.floor(Math.random() * x.length)];
}).join('');
}).concat().join('').split('').sort(function(){
return 0.5-Math.random();
}).join('')
}
// invoke like so: randPassword(5,3,2);
Run Code Online (Sandbox Code Playgroud)
同样的事情,作为一个2线程(诚然,非常长和丑陋的线 - 如果你使用适当的随机播放功能将不会是1线.不推荐,但有时它很有趣):
var chars = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz","0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"];
var randPwd = [5,3,2].map(function(len, i) { return Array(len).fill(chars[i]).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('') }).concat().join('').split('').sort(function(){return 0.5-Math.random()}).join('');
Run Code Online (Sandbox Code Playgroud)
小智 9
使用 Math.random() 生成的任何密码都是极其糟糕的。
该函数使用系统时间作为随机数生成器的种子。任何知道密码生成时间的人都可以轻松暴力破解密码。
在几乎所有情况下,这些数据都很容易获得 - 只需获取被黑数据库中的 Registration_time 列,并使用 15 到 0 分钟之前的时间测试 Math.random() 算法生成的所有值。
使用 Math.random() 生成的密码完全没有价值,因为密码第一次使用的时间足以破解它。
这不是完全优化的,但它应该工作.
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 8;
var randomstring = '';
var charCount = 0;
var numCount = 0;
for (var i=0; i<string_length; i++) {
// If random bit is 0, there are less than 3 digits already saved, and there are not already 5 characters saved, generate a numeric value.
if((Math.floor(Math.random() * 2) == 0) && numCount < 3 || charCount >= 5) {
var rnum = Math.floor(Math.random() * 10);
randomstring += rnum;
numCount += 1;
} else {
// If any of the above criteria fail, go ahead and generate an alpha character from the chars string
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum,rnum+1);
charCount += 1;
}
}
alert(randomstring);
Run Code Online (Sandbox Code Playgroud)
这是一个jsfiddle供您测试:http://jsfiddle.net/sJGW4/3/
正如@RobW 指出的那样,将密码限制为 OP 方案中提出的固定数量的字符是一个坏主意。但更糟糕的是,提出基于代码的答案是Math.random一个非常糟糕的主意。
让我们从坏主意开始。OP 代码从一组 62 个字符中随机选择一个包含 8 个字符的字符串。将随机字符串限制为 5 个字母和 3 个数字意味着生成的密码最多将具有28.5 位的熵(与 47.6 位的潜力相反)如果取消了 5 个字母和 3 个数字的分配限制)。那不是很好。但实际上,情况更糟。所述充其量代码的方面是通过使用破坏Math.random作为密码产生熵的手段。Math.random是一个伪随机数生成器。由于伪随机数生成器的确定性,生成的密码的熵非常糟糕,使任何此类提议的解决方案都成为一个非常糟糕的主意。假设这些密码被分发给最终用户(o/w 有什么意义),收到这样的密码的活跃对手很有可能预测未来分发给其他用户的密码,这可能不是一件好事。
但回到刚才的坏主意。假设使用密码强的伪随机数生成器而不是Math.random。为什么要将密码限制为 28.5 位?如前所述,这不是很好。想必5个字母3个数字的方案是为了帮助用户管理随机分发的密码。但是让我们面对它,你必须平衡易用性对使用的价值和熵的28.5位不是针对主动攻击防御多少价值。
但坏事已经够多了。让我们提出一条前进的道路。我将使用 JavaScript EntropyString库,它“有效地从各种字符集生成指定熵的加密强随机字符串”。而不是 OP 62 个字符,我将使用一个包含 32 个字符的字符集,以减少使用容易混淆的字符或英文单词的形成。而不是 5 个字母、3 个数字方案(它的熵太少),我将宣布密码将具有 60 位的熵(这是易用性与价值的平衡)。
import { Entropy, charSet32 } from 'entropy-string'
const random = new Entropy({ bits: 60, charset: charset32 })
const string = random.string()
Run Code Online (Sandbox Code Playgroud)
“Q7LfR8Jn7RDp”
请注意Entropy指定所需熵位的参数,而不是更常见的随机字符串生成解决方案,该解决方案指定传入字符串长度(这既被误导又通常未指定,但这是另一回事)。
小智 6
我写了一个小答案,灵感来自你的答案:
(function(){g=function(){c='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';p='';for(i=0;i<8;i++){p+=c.charAt(Math.floor(Math.random()*62));}return p;};p=g();while(!/[A-Z]/.test(p)||!/[0-9]/.test(p)||!/[a-z]/.test(p)){p=g();}return p;})()
Run Code Online (Sandbox Code Playgroud)
此函数返回密码,可以在bookmarklet中使用,如:
javascript:alert(TheCodeOfTheFunction);
Run Code Online (Sandbox Code Playgroud)
如果您需要使用至少1个数字,1个大写字母和1个小写字母生成的密码:
function generatePassword(passwordLength) {
var numberChars = "0123456789";
var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var lowerChars = "abcdefghijklmnopqrstuvwxyz";
var allChars = numberChars + upperChars + lowerChars;
var randPasswordArray = Array(passwordLength);
randPasswordArray[0] = numberChars;
randPasswordArray[1] = upperChars;
randPasswordArray[2] = lowerChars;
randPasswordArray = randPasswordArray.fill(allChars, 3);
return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
alert(generatePassword(12));
Run Code Online (Sandbox Code Playgroud)
如果您想玩/测试,这里是小提琴:http : //jsfiddle.net/sJGW4/155/
推荐给@mwag,让我开始创建它。
对于正在寻找最简单脚本的人.不while (true),不if/else,没有声明.
基于mwag的答案,但这个使用crypto.getRandomValues,比一个更强的随机Math.random.
Array(20)
.fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
.map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)])
.join('');
Run Code Online (Sandbox Code Playgroud)
看到这个神奇的魔力0xffffffff.
打开控制台并自己测试:
for (let i = 0 ; i < 100; i++)
console.log(
Array(20)
.fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
.map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)])
.join('')
)
Run Code Online (Sandbox Code Playgroud)
如果考虑性能,可以试试这个:
var generate = (
length = 20,
wishlist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
) => Array(length)
.fill('') // fill an empty will reduce memory usage
.map(() => wishlist[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * wishlist.length)])
.join('');
// Generate 100 passwords
for (var i = 0; i < 100; i++) console.log(generate());
Run Code Online (Sandbox Code Playgroud)
我对这个问题的基于加密的看法。使用 ES6 并省略任何浏览器功能检查。对安全性或性能有何评论?
const generatePassword = (
passwordLength = 12,
passwordChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
) =>
[...window.crypto.getRandomValues(new Uint32Array(passwordLength))]
.map(x => passwordChars[x % passwordChars.length])
.join('');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
89057 次 |
| 最近记录: |