Password Generator - Casuali, alfanumeriche e di lunghezza variabile

Password Generator

La scorsa settimana mi sono imbattuto su Linkedin in un post che parlava di componenti e sicurezza. Nei giorni scorsi ho cominciato a scriverne uno mio da rilasciare appena terminato come pacchetto nuget.

In tutta onestà ho già la Pull Request su GitHub per poi fare scattare il build e la creazione del pacchetto, ma ho ancora qualcosa che non mi convince dal punto di vista delle classi come organizzazione e nomenclatura. Non appena avrò risolto questo dilemma sarò ben felice di rendere pubblico il tutto ed aggiornare questo articolo col link del pacchetto.

In questo breve articolo verrà mostrata la classe C# scritta per generare password alfanumeriche di lunghezza variabile a piacevole.

Definizione using

1
2
3
using System;
using System.Collections.Generic;
using System.Linq;

class PasswordGenerator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class PasswordGenerator
{
    private readonly int[] UPPER_CASE = Enumerable.Range(65, 26).ToArray();
    private readonly int[] LOWER_CASE = Enumerable.Range(97, 26).ToArray();
    private readonly int[] NUMERIC_CASE = Enumerable.Range(48, 10).ToArray();
    private readonly int[] SPECIAL_CASE_RANGE1 = Enumerable.Range(32, 16).ToArray();
    private readonly int[] SPECIAL_CASE_RANGE2 = Enumerable.Range(58, 7).ToArray();
    private readonly int[] SPECIAL_CASE_RANGE3 = Enumerable.Range(91, 6).ToArray();
    private readonly int[] SPECIAL_CASE_RANGE4 = Enumerable.Range(123, 4).ToArray();

    private Queue<string> _chars = null;

    private string NextChar
    {
        get
        {
            if (_chars == null || _chars.Count == 0)
            {
                List<int> c = new List<int>();
                c.AddRange(UPPER_CASE);
                c.AddRange(LOWER_CASE);
                c.AddRange(NUMERIC_CASE);
                c.AddRange(SPECIAL_CASE_RANGE1);
                c.AddRange(SPECIAL_CASE_RANGE2);
                c.AddRange(SPECIAL_CASE_RANGE3);
                c.AddRange(SPECIAL_CASE_RANGE4);

                var d = c
                        .Select(x => ((char)x).ToString())
                        .OrderBy(x => Guid.NewGuid())
                        .ToList();

                _chars = new Queue<string>(d);
            }

            return _chars.Dequeue();
        }
    }

    public string Get(int length)
    {
        string result = string.Empty;

        for (int i = 0; i < length; i++)
        {
            result += this.NextChar;
        }

        return result;
    }
}

Utilizzo

Per utilizzare la classe PasswordGenerator il procedimento è davvero semplice. Basterà istanziarla e chiamare il metodo Get fornendo come parametro un numero intero che indicherà di quanti caratteri sarà la nostra password fornita come valore di ritorno.

1
2
3
4
5
6
7
string pwd = string.Empty;

PasswordGenerator password = new PasswordGenerator();
for (int i = 0; i < 100; i++)
{
    pwd = password.Get(12);
}

Nell’esempio di utilizzo appena proposto sono state generate 100 password con lunghezza di 12 caratteri.

FAQ

Domanda: cosa succede se la lunghezza della password è maggiore dei caratteri presente e non ancora utilizzati? Risposta: questo non è un problema. Ho utilizzato intenzionalmente una Queue per mettere tutti i caratteri da utilizzare per la generazione. Utilizzando sempre il Dequeue prendo il primo elemento per poi rimuoverlo. Nel momento in cui la Queue è vuota viene ricalcolata mescolando tutti i caratteri

Domanda: Devo utilizzare tutti i caratteri speciali che hai inserito? Oppure posso usarne meno? Risposta: Puoi usare i caratteri che vuoi! Ho definito i caratteri da usare in una serie di private readonly int[] in testa alla classe. Puoi rimuovere quelli che non desideri commentandoli e/o togliendoli quando creo la super lista con AddRange.

Domanda: Una volta istanziata la classe, quante password posso generare? Risposta: Da zero ad infinite! Non mi pongo problemi di quante password dovrai generare. Come detto in una risposta precedente, la Queue dei caratteri viene sempre rigenerata quando si trova senza elementi.

Domanda: Un esempio di contesto per questo codice? Risposta: Il classico ‘Ho dimenticato la password’ oppure la registrazione con la password inviata per email. Questi sonno i primi due che mi vengono in mente, ma non sono gli unici.