Генерация случайной строки пароля с требованиями в javascript
Я хочу создать случайную строку, которая должна иметь 5 букв из a-z и 3 числа.
Как я могу сделать это с помощью JavaScript?
У меня есть следующий скрипт, но он не соответствует моим требованиям.
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);
}
13 ответов:
принудительное фиксированное количество символов-это плохо идея. Это не улучшает качество пароля. Хуже того, это уменьшает количество возможных паролей, так что взлом с помощью bruteforcing становится проще.
чтобы создать случайное слово, состоящее из буквенно-цифровых символов, используйте:
var randomstring = Math.random().toString(36).slice(-8);как это работает?
Math.random() // Generate random number, eg: 0.123456 .toString(36) // Convert to base-36 : "0.4fzyo82mvyr" .slice(-8);// Cut off last 8 characters : "yo82mvyr"документация
Number.prototype.toStringиstring.prototype.sliceметоды.
немного более ремонтопригодный и надежный подход.
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(''); } };<input type='text' id='p'/><br/> <input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>
многие ответы (включая оригинал этого) не касаются требований к буквам и числам в OP. Ниже приведены два решения: общие (без минимальных букв/цифр) и с правилами.
общие:
Я считаю, что это более общее решение, чем выше, потому что:
- это более безопасный, чем принятый/самый высокий голос ответ, а также более универсальный, потому что он поддерживает любой набор символов с учетом регистра манера
- это более лаконично, чем другие ответы (для общего решения, 3 линии Макс; может быть один лайнер)
- он использует только родной Javascript - не требуется установка или другие библиотеки
отметим, что
- для этого нужно работать на IE, массив.заполнить() прототип должен быть polyfilled
- если возможно, лучше использовать окно.криптографический.getRandomValues () вместо Math.random () (спасибо @BenjaminH за указание вон)
три лайнера:
var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; var pwdLen = 10; var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');или, как один-лайнер:
var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');С Буквой / Номером Правил
теперь, вариация на тему выше. Это создаст три случайные строки из заданных наборов символов (буква, число, либо), а затем скремблировать результат.
обратите внимание, использует sort() и только в иллюстративных целях. Для производственного использования замените приведенную ниже функцию sort() на перетасовка функции, такие как Durstenfeld.
во-первых, как функция:
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);то же самое, что и 2-liner (по общему признанию, очень длинные и уродливые линии-и не будет 1-liner, если вы используете правильную функцию перемешивания. Не рекомендуется, но иногда это весело в любом случае) :
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('');
Это не совсем оптимизирована, но это должно работать.
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);
вот jsfiddle для вас, чтобы проверить на:http://jsfiddle.net/sJGW4/3/
Я написал небольшой вдохновленный вашим ответом:
(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;})()эта функция возвращает пароль и может быть использована в букмарклете, например:
javascript:alert(TheCodeOfTheFunction);
для тех, кто ищет простой скрипт. Нет
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 + 1))]) .join('');посмотреть этой для магии
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 + 1))]) .join('') )
если вы рассматриваете производительность, вы можете попробовать это:
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 + 1))]) .join(''); // Generate 100 passwords for (var i = 0; i < 100; i++) console.log(generate());
Если вам нужен пароль, сгенерированный по крайней мере с 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));вот скрипка, если вы хотите играть / тест:http://jsfiddle.net/sJGW4/155/
реквизит к @mwag для того, чтобы дать мне начало, чтобы создать это.
var letters = ['a','b','c','d','e','f','g','h','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; var numbers = [0,1,2,3,4,5,6,7,8,9]; var randomstring = ''; for(var i=0;i<5;i++){ var rlet = Math.floor(Math.random()*letters.length); randomstring += letters[rlet]; } for(var i=0;i<3;i++){ var rnum = Math.floor(Math.random()*numbers.length); randomstring += numbers[rnum]; } alert(randomstring);
Я бы не рекомендовал использовать принудительный пароль, поскольку он ограничивает безопасность пользователя, но в любом случае, есть несколько способов сделать это -
Традиционный Метод JavaScript -
Math.random().toString(36).slice(-8);С Помощью Случайной Строки
установить произвольную строку:
npm install randomstringиспользуя его в приложение.js -
var randStr = require('randomstring'); var yourString = randStr.generate(8);значение вашего пароля удерживается в переменной
yourString.не используйте принудительный пароль!
Принудительное Пароль может нанести вред вашей безопасности, так как все пароли будут находиться под одним и тем же набором символов, который может быть легко нарушен!
как отмечает @RobW, ограничение пароля фиксированным числом символов, как это предлагается в схеме OP, является плохая идея. Но хуже того, ответы, которые предлагают код на основе
Math.random, ну, а плохая идея.давайте начнем с плохая идея. Код OP случайным образом выбирает строку из 8 символов из набора 62. Ограничение случайной строки до 5 букв и 3 цифр означает, что результирующие пароли будут есть, в лучшем случае, 28.5 бит энтропии (в отличие от потенциала 47.6 бит, если ограничение распределения 5 букв и 3 цифры были удалены). Это не очень хорошо. Но на самом деле ситуация еще хуже. Элемент в лучшем случае аспект кода уничтожается с помощью
Math.randomкак средство генерации энтропии для паролей.Math.randomэто генератор псевдослучайных чисел. Из-за детерминизма природа генераторов псевдослучайных чисел энтропия результирующих паролей очень плохо, делая любое такое предлагаемое решение плохая идея. Предполагая, что эти пароли раздаются конечным пользователям (o/w what's point), активный противник, который получает такой пароль, имеет очень хорошие шансы предсказать будущие пароли, раздаваемые другим пользователям, и это, вероятно, не очень хорошо.Но вернемся к просто плохая идея. Предположим, что вместо . Почему вы ограничиваете пароли до 28,5 бит? Как уже отмечалось, это не очень хорошо. Предположительно, схема 5 букв, 3 цифры должна помочь пользователям в управлении случайно раздаваемыми паролями. Но давайте посмотрим правде в глаза, вы должны сбалансировать простота использования против значение использования, и 28.5 бит энтропии не имеет большого значения в защите от активного противник.
но хватит о плохом. Давайте предложим путь вперед. Я буду использовать JavaScript EntropyString библиотека, которая "эффективно генерирует криптографически сильные случайные строки заданной энтропии из различных наборов символов". Вместо символов OP 62 я буду использовать набор символов с 32 символами, выбранными для уменьшения использования легко запутанных символов или формирования английских слов. И вместо 5 букв, 3 числовая схема (которая тоже имеет маленькая энтропия), я объявлю, что пароль будет иметь 60 бит энтропии (это баланс легкости и ценности).
import {Random, charSet32} from 'entropy-string' const random = new Random(charSet32) const string = random.string(60)"Q7LfR8Jn7RDp"
обратите внимание на аргумент
random.string- это желаемые биты энтропии, в отличие от более часто встречающихся решений для генерации случайных строк, которые определяют передачу длины строки (что является как ошибочным, так и обычно недостаточно определенным, но это другая история).
и, наконец, без использования хаков с плавающей запятой:
function genpasswd(n) { // 36 ** 11 > Number.MAX_SAFE_INTEGER if (n > 10) throw new Error('Too big n for this function'); var x = "0000000000" + Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(36); return x.slice(-n); }
есть генератор случайных строк пароля с выбранной длиной
let input = document.querySelector("textarea"); let button = document.querySelector("button"); let length = document.querySelector("input"); function generatePassword(n) { let pwd = ""; while(!pwd || pwd.length < n) { pwd += Math.random().toString(36).slice(-22); } return pwd.substring(0, n); } button.addEventListener("click", function() { input.value = generatePassword(length.value); });<div>password:</div> <div><textarea cols="70" rows="10"></textarea></div> <div>length:</div> <div><input type="number" value="200"></div> <br> <button>gen</button>
безопасный пароль с одним прописным символом.
let once = false; let newPassword = Math.random().toString(36).substr(2, 8).split('').map((char) => { if(!Number(char) && !once){ once = true; return char.toUpperCase(); } return char; }).join(''); console.log(newPassword)
Comments