Password generator in C#
Questa funzione statica in C# (PasswordGenerator.Generate) permette di generare una password in modo casuale in funzione dei parametri passati.
Il primo parametro options, indica i criteri validi per la scelta dei caratteri che verranno usati per la generazione della password:
Il secondo parametro, opzionale, len è la lunghezza della password generata (default 10).
Il terzo è ultimo parametro, anch'esso opzionale, charactersToExclude è una stringa di caratteri da escludere dalla generazione.
Esempio di utilizzo:
Un tool online lo trovi a questa pagina Password Generator Advanced
I parametri sono: options, len e charactersToExclude.Il primo parametro options, indica i criteri validi per la scelta dei caratteri che verranno usati per la generazione della password:
- upper: include i caratteri alfabetici maiuscoli (A-Z)
- lower: include i caratteri alfabetici minuscoli (a-z)
- number: include i caratteri numerici (0-9)
- minus: include il carattere meno (-)
- underscore: include il carattere trattino basso (_)
- space: include il carattere spazio ( )
- special: include un set di caratteri speciali (!\"#$%&\'*+,./=;=?@\\^`|~)
- specialIT: include un altro set di caratteri speciali (£€§°ç)
- specialSimple: include un altro set di caratteri speciali (!$%-*+@)
- parentesis: include i caratteri di tipo parentesi ( ()[]{}<> )
- accent: include i caratteri alfabetici che rappresentano le lettere accentate, sia maiuscole che minuscole (àáâåãäçèéêëìíîïñóòôøõöúùûüßÿÀÁÂÅÃÄÇÈÉÊËÌÍÎÏÑÓÒÔØÕÖÚÙÛÜߟ)
- nosimilar: esclude i caratteri che, a livello visivo, sembrano simili (|I1li0Oo)
Il secondo parametro, opzionale, len è la lunghezza della password generata (default 10).
Il terzo è ultimo parametro, anch'esso opzionale, charactersToExclude è una stringa di caratteri da escludere dalla generazione.
C#
using System;
using System.Collections.Generic;
using System.Text;
namespace Sgart.Utility
{
/// <summary>
/// Sgart.it - https://www.sgart.it/IT/informatica/password-generator-in-c/post
/// </summary>
public static class PasswordGenerator
{
static readonly List<OptionItem> allOptions = new List<OptionItem> {
new OptionItem{ID=OptionKey.Upper , Text= "Maiuscolo", Value= "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Add= true },
new OptionItem{ID= OptionKey.Lower, Text= "Minuscolo", Value= "abcdefghijklmnopqrstuvwxyz", Add= true },
new OptionItem{ID= OptionKey.Number, Text= "Numeri", Value= "0123456789", Add= true },
new OptionItem{ID= OptionKey.Minus, Text= "Meno", Value= "-", Add= true },
new OptionItem{ID= OptionKey.Underscore, Text= "Trattino basso", Value= "_", Add= true },
new OptionItem{ID= OptionKey.Space, Text= "Spazio", Value= " ", Add= true },
new OptionItem{ID= OptionKey.Special, Text= "Speciali", Value= "!\"#$%&\'*+,./=;=?@\\^`|~", Add= true},
new OptionItem{ID= OptionKey.SpecialIT, Text= "Speciali Italiani", Value= "£€§°ç", Add= true },
new OptionItem{ID= OptionKey.SpecialSimple, Text= "Speciali semplici", Value= "!$%-*+@", Add= true },
new OptionItem{ID= OptionKey.Parentesis, Text= "Parentesi", Value= "()[]{}<>", Add= true },
new OptionItem{ID= OptionKey.Accent, Text= "Lettere accentate", Value= "àáâåãäçèéêëìíîïñóòôøõöúùûüßÿÀÁÂÅÃÄÇÈÉÊËÌÍÎÏÑÓÒÔØÕÖÚÙÛÜߟ", Add= true },
new OptionItem{ID= OptionKey.NoSimilar, Text= "Caratteri simili", Value= "|I1li0Oo", Add= false },
};
static readonly char[] SEP = { (char)10 };
public static string Generate(int len = 10)
{
return Generate(OptionKey.Default, len);
}
public static string Generate(string options, int len = 10, string charactersToExclude = null)
{
OptionKey opt = ParseOptionKeyFromString(options);
return Generate(opt, len, charactersToExclude);
}
public static string Generate(OptionKey options, int len = 10, string charactersToExclude = null)
{
StringBuilder result = new StringBuilder();
string[] charset = BuildValidCaracters(options, charactersToExclude);
int m = charset.Length;
// mi assicuro di avere almeno un carattere per tipo
for (int i = 0; i < m; i++)
{
// li scambio di sequenza casulamente
string values = charset[i] = ExhangeCharactersRandom(charset[i]);
// prendo un carattere a caso
var c = GeneratorRnd(values.Length);
result.Append(values[c]);
}
// poi aggiungo gli altri
string validChars = string.Join("", charset);
m = validChars.Length;
while (result.Length < len)
{
//validChars = ExhangeCharactersRandom(validChars);
var p = GeneratorRnd(m);
if (p >= m)
throw new ArgumentException("PasswordGenerator: char wrong: " + p);
result.Append(validChars[p]);
}
return ExhangeCharactersRandom(result.ToString());
}
static string[] BuildValidCaracters(OptionKey options, string charactersToExclude = null)
{
StringBuilder sbAdd = new StringBuilder();
StringBuilder sbRemove = new StringBuilder();
if (charactersToExclude != null)
{
sbRemove.Append(charactersToExclude);
}
foreach (var item in allOptions)
{
if ((item.ID & options) != 0)
{
if (item.Add)
{
sbAdd.Append(item.Value);
sbAdd.Append(SEP);
}
else
sbRemove.Append(item.Value);
}
}
if (sbRemove.Length == 0)
{
return sbAdd.ToString().Split(SEP, StringSplitOptions.RemoveEmptyEntries);
}
else
{
// tolgo i caratteri da escludere
StringBuilder result = new StringBuilder();
string toRemove = sbRemove.ToString();
for (int i = 0; i < sbAdd.Length; i++)
{
var c = sbAdd[i];
if (toRemove.Contains(c.ToString()) == false)
result.Append(c);
}
return result.ToString().Split(SEP, StringSplitOptions.RemoveEmptyEntries);
}
}
static string ExhangeCharactersRandom(string s)
{
var sb = s.ToCharArray();
var m = sb.Length;
for (var i = 0; i < m; i++)
{
var p1 = GeneratorRnd(m);
var p2 = GeneratorRnd(m);
var t = sb[p2];
sb[p2] = sb[p1];
sb[p1] = t;
}
return new string(sb);
}
static Random rnd = new Random();
static int GeneratorRnd(int n)
{
return rnd.Next(0, n);
}
/// <summary>
/// stringhe di opzioni separate da pipe
/// es: upper|lower|number
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
static OptionKey ParseOptionKeyFromString(string options)
{
OptionKey result = OptionKey.Unknow;
var opt = options.Split(new char[] { '|', ';', ',' });
foreach (var s in opt)
{
OptionKey k;
if (Enum.TryParse<OptionKey>(s, true, out k) == false)
throw new ArgumentException($"PasswordGenerator: invalid key: {s}");
result |= k;
}
return result;
}
}
class OptionItem
{
public OptionKey ID { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public bool Add { get; set; }
}
public enum OptionKey
{
Unknow = 0x0000,
Upper = 0x0001,
Lower = 0x0002,
Number = 0x0004,
Minus = 0x0008,
Underscore = 0x0010,
Space = 0x0020,
Special = 0x0040,
SpecialIT = 0x0080,
SpecialSimple = 0x0800,
Parentesis = 0x0100,
Accent = 0x0200,
NoSimilar = 0x0400,
LettersNumber = Upper | Lower | Number | Minus,
Default = Upper | Lower | Number | Minus | Underscore | Special | NoSimilar,
All = 0xFFFF
}
}
C#
var pwd = PasswordGenerator.Generate("upper,lower",11); // es.: "jUPbNLyTezj"
var pwd = PasswordGenerator.Generate("upper,lower,number,NoSimilar", 11, "aA239"); // es.: "4qCpvNYH4EH"