Генерация случайной строки пароля с требованиями в 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);
}
435   13  

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

    Ничего не найдено.