-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_password
137 lines (116 loc) · 5.97 KB
/
generate_password
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Handwritten readable passwords. Written by Valentijn Peters
// is it a 0 or a O, an l or a I?? that is history!
// https://dotnetfiddle.net/7kVSpO
using System;
using System.Text.RegularExpressions;
using CodeShare.Library.Passwords;
public class Program
{
public static void Main()
{
bool includeLowercase = false;
bool includeUppercase = true;
bool includeNumeric = true;
bool includeSpecial = false;
bool includeSpaces = false;
int lengthOfPassword = 10;
string password = PasswordGenerator.GeneratePassword(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, lengthOfPassword);
while(!PasswordGenerator.PasswordIsValid(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, password))
{
password = PasswordGenerator.GeneratePassword(includeLowercase, includeUppercase, includeNumeric, includeSpecial, includeSpaces, lengthOfPassword);
}
Console.WriteLine(password);
}
}
namespace CodeShare.Library.Passwords
{
public static class PasswordGenerator
{
/// <summary>
/// Generates a random password based on the rules passed in the parameters
/// </summary>
/// <param name="includeLowercase">Bool to say if lowercase are required</param>
/// <param name="includeUppercase">Bool to say if uppercase are required</param>
/// <param name="includeNumeric">Bool to say if numerics are required</param>
/// <param name="includeSpecial">Bool to say if special characters are required</param>
/// <param name="includeSpaces">Bool to say if spaces are required</param>
/// <param name="lengthOfPassword">Length of password required. Should be between 8 and 128</param>
/// <returns></returns>
public static string GeneratePassword(bool includeLowercase, bool includeUppercase, bool includeNumeric, bool includeSpecial, bool includeSpaces, int lengthOfPassword)
{
const int MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS = 2;
const string LOWERCASE_CHARACTERS = "abdefghjmnqrty";
const string UPPERCASE_CHARACTERS = "ABDEFGHJLMNQRTVWXY";
const string NUMERIC_CHARACTERS = "23456789";
const string SPECIAL_CHARACTERS = @"!#$%&*@\";
const string SPACE_CHARACTER = " ";
const int PASSWORD_LENGTH_MIN = 8;
const int PASSWORD_LENGTH_MAX = 128;
if (lengthOfPassword < PASSWORD_LENGTH_MIN || lengthOfPassword > PASSWORD_LENGTH_MAX)
{
return "Password length must be between 8 and 128.";
}
string characterSet = "";
if (includeLowercase)
{
characterSet += LOWERCASE_CHARACTERS;
}
if (includeUppercase)
{
characterSet += UPPERCASE_CHARACTERS;
}
if (includeNumeric)
{
characterSet += NUMERIC_CHARACTERS;
}
if (includeSpecial)
{
characterSet += SPECIAL_CHARACTERS;
}
if (includeSpaces)
{
characterSet += SPACE_CHARACTER;
}
char[] password = new char[lengthOfPassword];
int characterSetLength = characterSet.Length;
System.Random random = new System.Random();
for (int characterPosition = 0; characterPosition < lengthOfPassword; characterPosition++)
{
password[characterPosition] = characterSet[random.Next(characterSetLength - 1)];
bool moreThanTwoIdenticalInARow =
characterPosition > MAXIMUM_IDENTICAL_CONSECUTIVE_CHARS
&& password[characterPosition] == password[characterPosition - 1]
&& password[characterPosition - 1] == password[characterPosition - 2];
if (moreThanTwoIdenticalInARow)
{
characterPosition--;
}
}
return string.Join(null, password);
}
/// <summary>
/// Checks if the password created is valid
/// </summary>
/// <param name="includeLowercase">Bool to say if lowercase are required</param>
/// <param name="includeUppercase">Bool to say if uppercase are required</param>
/// <param name="includeNumeric">Bool to say if numerics are required</param>
/// <param name="includeSpecial">Bool to say if special characters are required</param>
/// <param name="includeSpaces">Bool to say if spaces are required</param>
/// <param name="password">Generated password</param>
/// <returns>True or False to say if the password is valid or not</returns>
public static bool PasswordIsValid(bool includeLowercase, bool includeUppercase, bool includeNumeric, bool includeSpecial, bool includeSpaces, string password)
{
const string REGEX_LOWERCASE = @"[a-z]";
const string REGEX_UPPERCASE = @"[A-Z]";
const string REGEX_NUMERIC = @"[\d]";
const string REGEX_SPECIAL = @"([!#$%&*@\\])+";
const string REGEX_SPACE = @"([ ])+";
bool lowerCaseIsValid = !includeLowercase || (includeLowercase && Regex.IsMatch(password, REGEX_LOWERCASE));
bool upperCaseIsValid = !includeUppercase || (includeUppercase && Regex.IsMatch(password, REGEX_UPPERCASE));
bool numericIsValid = !includeNumeric || (includeNumeric && Regex.IsMatch(password, REGEX_NUMERIC));
bool symbolsAreValid = !includeSpecial || (includeSpecial && Regex.IsMatch(password, REGEX_SPECIAL));
bool spacesAreValid = !includeSpaces || (includeSpaces && Regex.IsMatch(password, REGEX_SPACE));
return lowerCaseIsValid && upperCaseIsValid && numericIsValid && symbolsAreValid && spacesAreValid;
}
}
}