Wygeneruj losowy ciąg haseł z wymaganiami w javascript


96

Chcę wygenerować losowy ciąg zawierający 5 liter od az i 3 cyfry.

Jak mogę to zrobić za pomocą JavaScript?

Mam następujący skrypt, ale nie spełnia on moich wymagań.

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

6
Jeśli spełnia twoje wymagania, jakie jest pytanie? Poza tym wymuszone hasło to zły pomysł.
Rob W


3
new Array(12).fill().map(() => String.fromCharCode(Math.random()*86+40)).join("") Sprytna wkładka do tworzenia 12-znakowego hasła ze specjalnymi górnymi dolnymi liczbami znaków w bardzo lekkim podejściu
Tofandel

Odpowiedzi:


318

Wymuszenie określonej liczby znaków to zły pomysł. Nie poprawia jakości hasła. Co gorsza, zmniejsza liczbę możliwych haseł, dzięki czemu hakowanie przez brutalne staje się łatwiejsze.

Aby wygenerować losowe słowo składające się ze znaków alfanumerycznych, użyj:

var randomstring = Math.random().toString(36).slice(-8);

Jak to działa?

Math.random()                        // Generate random number, eg: 0.123456
             .toString(36)           // Convert  to base-36 : "0.4fzyo82mvyr"
                          .slice(-8);// Cut off last 8 characters : "yo82mvyr"

Dokumentacja metod Number.prototype.toStringi string.prototype.slice.


6
Zgadzam się, ale czasami nie możesz się zdecydować;)
ffffff01

40
NIE UŻYWAJ TEGO: Ponieważ liczba jest konwertowana z binarnej na dziesiętną i nie ma wystarczającej liczby bitów, aby „wypełnić” całą przestrzeń dziesiętną, ostatnia cyfra zostanie wybrana tylko z określonego zestawu wartości. Na przykład na moim komputerze ostatnią cyfrą jest zawsze tylko „i”, „r” i „9”. Użyj tego zamiast tego:Math.random().toString(36).substr(2, 8)
Joel

1
Aby wyjaśnić, co robi 36: Z mozilli Metoda toString () analizuje swój pierwszy argument i próbuje zwrócić reprezentację w postaci łańcucha o określonej podstawie (podstawie). W przypadku podstaw powyżej 10 litery alfabetu oznaczają cyfry większe niż 9. Na przykład w przypadku liczb szesnastkowych (podstawa 16) stosuje się od a do f. Zgodnie z tym, używając radix 36, otrzymujemy az po 0-9.
Shishir Gupta

2
@ShishirGupta .toStringakceptuje tylko bazę do 36 włącznie. Ta odpowiedź jest rozumiana jako jednowierszowy dla niekryptograficznego losowego ciągu. Jeśli chcesz mieć również wielkie litery, użyj Math.random(lub crypto.getRandomValuesjeśli jest dostępny) i zamapuj wynik na az, AZ, 0-9. Na przykład używając odpowiedzi Saaja poniżej.
Rob W

1
Nie widząc, w jaki sposób odnosi się to do wymagania OP „5 liter od az i 3 cyfry” . Rozumiem, autor uważa, że ​​to zły pomysł ... ale to jednak wymóg
mwag

39

Trochę łatwiejsze w utrzymaniu i bezpieczne podejście.

Aktualizacja, aby rozwinąć, co miałem na myśli i jak to działa.

  1. Bezpiecznie . MDN dość wyraźnie mówi o używaniu Math.random do wszystkiego związanego z bezpieczeństwem :

    Math.random() nie zawiera liczb losowych zabezpieczonych kryptograficznie. Nie używaj ich do niczego związanego z bezpieczeństwem. Zamiast tego użyj internetowego interfejsu API Crypto, a dokładniej window.crypto.getRandomValues()metody.

    Patrząc na can-i-use forgetRandomValues w 2020 roku, prawdopodobnie nie potrzebujesz już msCryptoi Math.randomfallback, chyba że interesują Cię starożytne przeglądarki.

  2. Maintainable to przede wszystkim RegExp _patternłatwy sposób definiowania klas znaków, na które zezwalasz w haśle. Ale także o trzech rzeczach, w których każdy wykonuje swoją pracę: definiuje wzorzec, pobiera losowy bajt tak bezpiecznie, jak to możliwe, zapewnia publiczny interfejs API do połączenia tych dwóch.

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)'>


Co więcej, to nie zawsze dodaje numer do wygenerowanego kodu, a OP chce minimum 3.
qwertzman

Znaleziono bibliotekę, która obsługuje window.crypto.getRandomValues ​​i działa również w node.js github.com/bermi/password-generator
Eugene

Chciałem tylko powiedzieć, że potrzebuję czegoś do generowania haseł w mgnieniu oka i to było idealne. Dziękuję Ci!
Kyle K

Proszę o wyjaśnienie, jak to działa?
Elijah Mock

30

Wiele odpowiedzi (w tym oryginał tej) nie dotyczy wymagań dotyczących liczby liter i cyfr w PO. Poniżej znajdują się dwa rozwiązania: ogólne (bez min liter / cyfr) oraz z regułami.

Generał:

Uważam, że jest to lepsze rozwiązanie ogólne niż powyższe, ponieważ:

  • jest bezpieczniejszy niż zaakceptowana / najwyżej głosowana odpowiedź, a także bardziej wszechstronny, ponieważ obsługuje dowolny zestaw znaków z uwzględnieniem wielkości liter
  • jest bardziej zwięzły niż inne odpowiedzi (dla rozwiązania ogólnego, maksymalnie 3 wiersze; może być jedno-wierszowy)
  • używa tylko natywnego Javascript - nie wymaga instalacji ani innych bibliotek

Zwróć na to uwagę

  • aby to działało w IE, prototyp Array.fill () musi być wypełniony
  • jeśli jest dostępny, lepiej użyć window.crypto.getRandomValues ​​() zamiast Math.random () (dzięki @BenjaminH za wskazanie)

Trzyrzędowa:

var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var pwdLen = 10;
var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

Lub jako jednowierszowe:

var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

Z regułami dotyczącymi liter / liczb

Teraz wariacja na temat powyższego. Spowoduje to wygenerowanie trzech losowych ciągów z podanych zestawów znaków (litery, cyfry lub), a następnie zaszyfrowanie wyniku.

Zwróć uwagę, że poniżej użyto sort () wyłącznie w celach ilustracyjnych. Do użytku produkcyjnego zamień poniższą funkcję sort () na funkcję shuffle, taką jak Durstenfeld .

Po pierwsze, jako funkcja:

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

To samo, co w przypadku linii 2-liniowej (trzeba przyznać, że bardzo długie i brzydkie linie - i nie będą liniami 1-liniowymi, jeśli użyjesz odpowiedniej funkcji tasowania. Niezalecane, ale czasami i tak jest fajne):

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('');

Dobra odpowiedź, ale duża litera Y nigdy nie pojawi się w żadnym generowanym haśle.
Ryan Shillington

1
Dzięki. Użyłem zestawu znaków w pytaniu OP, ale wygląda na to, że zawierał błąd. Zaktualizowano teraz.
mwag

Mówisz „jest bezpieczniejsza niż odpowiedź zaakceptowana / z największą liczbą głosów”. Czy mógłbyś wyjaśnić powód?
BenjaminH

Również użycie Math.random () może być przewidywalne. Więc do generowania haseł lepiej użyj funkcji takiej jak window.crypto.getRandomValues.
BenjaminH

2
Powodem jest to, że jest bezpieczniejszy, ponieważ obsługuje większą liczbę możliwych znaków w wyjściu niż użycie toString (36). Przy stałej długości wyjściowej (np. 8), jeśli masz maksymalnie 36 znaków do wyboru, masz znacznie mniej permutacji niż gdybyś miał 62 znaki (jak w przykładzie) lub jeszcze lepiej, całe 95 do wydrukowania (ascii ) znaków lub, jeśli używasz Unicode, jeszcze większą liczbę możliwości na bajt.
mwag

11

Dla kogoś, kto szuka najprostszego scenariusza. Nie while (true), nie if/else, bez deklaracji.

Opierając się na odpowiedzi mwag, ale ta używa crypto.getRandomValues, silniejszego losowego niż Math.random.

Array(20)
  .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
  .map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)])
  .join('');

Zobacz to na 0xffffffff.

Alternatywa 1

var generatePassword = (
  length = 20,
  wishlist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
) => Array(length)
      .fill('')
      .map(() => wishlist[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * wishlist.length)])
      .join('');

console.log(generatePassword());

Alternatywa 2

var generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.getRandomValues(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

Node.js

const crypto = require('crypto')

const generatePassword = (
  length = 20,
  wishlist = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.randomFillSync(new Uint32Array(length)))
    .map((x) => wishlist[x % wishlist.length])
    .join('')

console.log(generatePassword())

1
Nie jest to konsekwentne podawanie haseł o długości 20 z powodu niezdefiniowanego przesunięcia. + 1Część nie jest konieczne i może być usunięta.
bryc

Dobry chwyt @bryc. Zaktualizowano. Dzięki.
Ninh Pham

1
Przydatne i łatwe rozwiązanie. Każdy, kto chce to zrobić w NodeJS, może po prostu zastąpić crypto.getRandomValuesgo crypto.randomFillSync .
Rvy Pandey

Dodano wersję Node.js. Dzięki @Rvy Pandey.
Ninh Pham

8

Nie jest to dokładnie zoptymalizowane, ale powinno działać.

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

Wcześniejsze

Oto jsfiddle do przetestowania na: http://jsfiddle.net/sJGW4/3/


1
chars.substring(rnum, rnum+1)jest jakchars.charAt(rnum)
Mad Echet

8

Jak zauważa @RobW, ograniczenie hasła do stałej liczby znaków, jak zaproponowano w schemacie OP, jest złym pomysłem . Ale co gorsza, odpowiedzi, na podstawie których proponuje się kod Math.random, to naprawdę zły pomysł .

Zacznijmy od złego pomysłu . Kod OP losowo wybiera ciąg 8 znaków z zestawu 62. Ograniczenie losowego ciągu do 5 liter i 3 cyfr oznacza, że ​​otrzymane hasła będą miały co najwyżej 28,5 bitów entropii (w przeciwieństwie do potencjału 47,6 bitów jeśli zniesiono ograniczenie dystrybucji do 5 liter i 3 cyfr). To nie jest zbyt dobre. Ale w rzeczywistości sytuacja jest jeszcze gorsza. W najlepszym aspektem kod jest zniszczone przez stosowanie Math.randomjako środka generowania entropii dla haseł. Math.randomjest generatorem liczb pseudolosowych . Z powodu deterministycznej natury generatorów liczb pseudolosowych entropia haseł wynikowych jest naprawdę zła, co sprawia, że ​​każde takie proponowane rozwiązanie jest naprawdę złym pomysłem. Zakładając, że te hasła są przekazywane użytkownikom końcowym (o / w o co chodzi), aktywny przeciwnik, który otrzyma takie hasło, ma bardzo duże szanse na przewidzenie przyszłych haseł, które zostaną rozdane innym użytkownikom, a to prawdopodobnie nie jest dobra rzecz.

Ale wracając do złego pomysłu . Załóżmy, że zamiast niego jest używany silny kryptograficznie generator liczb pseudolosowych Math.random. Dlaczego miałbyś ograniczyć hasła do 28,5 bitów? Jak zauważono, to nie jest zbyt dobre. Przypuszczalnie schemat 5 liter i 3 cyfr ma pomóc użytkownikom w zarządzaniu losowo rozdawanymi hasłami. Ale spójrzmy prawdzie w oczy, musisz zrównoważyć łatwość użytkowania z wartością użytkową , a 28,5 bitów entropii nie ma zbytniej wartości w obronie przed aktywnym przeciwnikiem.

Ale dość zła. Zaproponujmy drogę naprzód. Użyję biblioteki JavaScript EntropyString, która „efektywnie generuje silne kryptograficznie ciągi losowe o określonej entropii z różnych zestawów znaków”. Zamiast znaków OP 62, użyję zestawu znaków z 32 znakami wybranymi, aby zmniejszyć użycie łatwo mylących się znaków lub tworzenia angielskich słów. Zamiast schematu 5-literowego i 3-liczbowego (który ma zbyt małą entropię), ogłoszę, że hasło będzie miało 60 bitów entropii (jest to równowaga między łatwością a wartością).

import { Entropy, charSet32 } from 'entropy-string'
const random = new Entropy({ bits: 60, charset: charset32 })
const string = random.string()

„Q7LfR8Jn7RDp”

Zwróć uwagę na argumenty Entropyokreślające pożądane bity entropii w przeciwieństwie do częściej spotykanych rozwiązań do losowego generowania ciągów, które określają przekazywanie długości ciągu (co jest zarówno błędne, jak i zwykle niedookreślone, ale to już inna historia).


Dziękuję Ci! Zwróć uwagę, że przykład tutaj już nie działa.
Geza Turi

1
Fragment kodu został zaktualizowany do nowszej wersji biblioteki. Wiele przykładów znajduje się również w bibliotece README i repozytorium GitHub.
dingo sky

7

W przypadku, gdy potrzebujesz hasła wygenerowanego z co najmniej 1 cyfry, 1 dużej litery i 1 małej litery:

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

Oto skrzypce, jeśli chcesz grać / testować: http://jsfiddle.net/sJGW4/155/

Podziękowania dla @mwag za rozpoczęcie tworzenia tego.


1
Brakuje małych liter j: P W przeciwnym razie dobre rzeczy tutaj. Zmodyfikowałem go jednak trochę, aby spełnić moje wymagania.
Igor Yavych

6

Napisałem małą, zainspirowaną Twoją odpowiedzią:

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

Ta funkcja zwraca hasło i może być używana w bookmarkletach, takich jak:

javascript:alert(TheCodeOfTheFunction);

3

Nie polecałbym używania wymuszonego hasła, ponieważ ogranicza to bezpieczeństwo użytkownika, ale w każdym razie jest na to kilka sposobów -

Tradycyjna metoda JavaScript -

Math.random().toString(36).slice(-8);

Korzystanie z losowego ciągu

Zainstaluj losowy ciąg:

npm install randomstring

Używanie go w App.js -

var randStr = require('randomstring');

var yourString = randStr.generate(8);

Wartość twojego hasła jest przechowywana w zmiennej yourString .

Nie używaj wymuszonego hasła!

Wymuszone hasło może zagrozić Twojemu bezpieczeństwu, ponieważ wszystkie hasła będą mieć ten sam zestaw znaków, który może być łatwo złamany!


3

Ok, więc jeśli dobrze rozumiem, próbujesz uzyskać losowe hasło ciągowe, które zawiera 5 liter i 3 cyfry losowo rozmieszczone, a więc ma długość 8 znaków i akceptujesz litery główne i minimalne, możesz to zrobić za pomocą następującej funkcji :

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}
console.log(randPass(5,3))


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

1

I wreszcie, bez używania hacków zmiennoprzecinkowych:

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

1

Bezpieczne hasło za pomocą jednego znaku wielkiej litery.

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)

1

Moje podejście do problemu oparte na Crypto. Używanie ES6 i pomijanie jakichkolwiek sprawdzeń funkcji przeglądarki. Masz uwagi na temat bezpieczeństwa lub wydajności?

const generatePassword = (
  passwordLength = 12,
  passwordChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
) =>
  [...window.crypto.getRandomValues(new Uint32Array(passwordLength))]
    .map(x => passwordChars[x % passwordChars.length])
    .join('');


1

Utwórz usługę generatora haseł o nazwie PassswordGeneratorService

import { Injectable } from '@angular/core';

@Injectable()
export class PasswordGeneratorService {

  generatePassword(length:number,upper:boolean,numbers:boolean,symbols:boolean) {
    const passwordLength = length || 12;
    const addUpper =  upper;
    const addNumbers =  numbers;
    const addSymbols =  symbols;

    const lowerCharacters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
    const upperCharacters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
    const numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    const symbols = ['!', '?', '@'];

    const getRandom = array => array[Math.floor(Math.random() * array.length)];

    let finalCharacters = '';

    if (addUpper) {
      finalCharacters = finalCharacters.concat(getRandom(upperCharacters));
    }

    if (addNumbers) {
      finalCharacters = finalCharacters.concat(getRandom(numbers));
    }

    if (addSymbols) {
      finalCharacters = finalCharacters.concat(getRandom(symbols));
    }

    for (let i = 1; i < passwordLength - 3; i++) {
      finalCharacters = finalCharacters.concat(getRandom(lowerCharacters));
    }

    return  finalCharacters.split('').sort(() => 0.5 - Math.random()).join('');
  }
}

nie zapomnij dodać usługi do modułu, którego używasz

@NgModule({
  imports: [
    CommonModule,
    SharedModule,
    CommonModule,
    RouterModule.forChild(routes),
    FormsModule,
    ReactiveFormsModule,
    FlexLayoutModule,
    TranslateModule,
    ExistingUserDialogModule,
    UserDocumentsUploadDialogModule
  ],
  declarations: [
    UserListComponent,
    EditUserDialogComponent,
    UserEditorComponent
  ],
  entryComponents: [
    EditUserDialogComponent
  ],
  providers: [
    AuthService,
    PasswordGeneratorService
  ]
})
export class UsersModule {
}

Na kontrolerze dodaj metodę, która wywoła metodę generowania hasła wewnątrz usługi i ustaw wynik w polu hasła

  constructor(
     private passwordGenerator: PasswordGeneratorService,
    )
  get newPassword() {
    return this.password.get('newPassword');
  }
  generatePassword() {
    this.newPassword.setValue(this.passwordGenerator.generatePassword(8,true,true,true));
  }

Po prostu usunąłem tę funkcję generatePasswordi użyłem jej, nie potrzebowałem całej klasy. thnx
Biskrem Muhammad

0

Istnieje generator ciągów haseł losowych o wybranej długości

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>


0

Cóż, zawsze możesz skorzystać z obiektu window.crypto dostępnego w najnowszej wersji przeglądarki.

Wystarczy jeden wiersz kodu, aby uzyskać losową liczbę:

let n = window.crypto.getRandomValues(new Uint32Array(1))[0];

Pomaga także w szyfrowaniu i odszyfrowywaniu danych. Więcej informacji w MDN Web Docs - window.crypto .


0

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)'>


0

Każde hasło wygenerowane za pomocą Math.random () jest BARDZO ZŁE .

Ta funkcja wykorzystuje czas systemowy jako ziarno dla generatora liczb losowych. Każdy, kto zna godzinę wygenerowania hasła, może łatwo je wymusić.

W prawie wszystkich przypadkach dane te są łatwo dostępne - wystarczy pobrać kolumnę registration_time w zhakowanej bazie danych i przetestować wszystkie wartości wygenerowane przez algorytm Math.random (), używając czasów od 15 do 0 minut wcześniej.

Hasło wygenerowane za pomocą Math.random () jest całkowicie bezwartościowe, ponieważ czas pierwszego użycia hasła wystarczy do jego złamania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.