-
-
Save ardagermiyanoglu/4ca70d597a5c6e44fe36 to your computer and use it in GitHub Desktop.
C# Console Password Generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
/* | |
* Code by: Christopher Ardelean | |
* Version 1.0 | |
* 2015-01-29 | |
* | |
* I had far too much fun with this one... | |
*/ | |
namespace Password_Generation | |
{ | |
class Program | |
{ | |
static char[] ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(); | |
static char[] alpha = "abcdefghijklmnopqrstuvwxyz".ToCharArray(); | |
static char[] numeric = "0123456789".ToCharArray(); | |
static char[] symbol = "!@#$%^&*()[]{};:'\",.<>/?\\|_+-=`~".ToCharArray(); | |
static string keyboard = "`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./"; | |
static string KEYBOARD = "~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?"; | |
static string[] units = { "Seconds", "Minutes", "Hours", "Days", "Weeks", "Years", "Decades", "Centuries", "Millenia" }; | |
static double[] unitValues = { 1, 60, 60, 24, 7, (365.242196 / 7), 10, 10, 10 }; // 365.242196 is a reasonable estimate for leap years | |
static void Main(string[] args) | |
{ | |
int length = 0; | |
int numberOfPass = 1; | |
bool uppercase = false; | |
bool lowercase = false; | |
bool num = false; | |
bool sym = false; | |
bool ASCII = false; | |
bool again = true; | |
while (again) | |
{ | |
Console.Clear(); | |
Console.WriteLine("Welcome to the password generator.\n"); | |
Console.WriteLine("Your current character sets are as follows:"); | |
Console.WriteLine("-------------------------------------------"); | |
ShowArray("Uppercase", ALPHA); | |
ShowArray("Lowercase", alpha); | |
ShowArray("Numerics", numeric); | |
ShowArray("Symbols", symbol); | |
AskInt("How long would you like your password to be", ref length, 1, 32); | |
AskInt("How many passwords would you like to generate", ref numberOfPass, 1, 20); | |
AskBool("the full ASCII page", ref ASCII); | |
if (!ASCII) | |
{ | |
Console.WriteLine(); | |
AskBool("uppercase", ref uppercase); | |
AskBool("lowercase", ref lowercase); | |
AskBool("numerics", ref num); | |
AskBool("symbols", ref sym); | |
} | |
generatePassword(ASCII, uppercase, lowercase, num, sym, length, numberOfPass); | |
AskBool("this tool again", ref again); | |
} | |
Console.WriteLine("Goodbye!"); | |
} | |
static void ShowArray(string name, char[] array) | |
{ | |
StringBuilder sb = new StringBuilder(80); | |
sb.Append(name); | |
sb.Append(":\t"); | |
for (int i = 0; i < array.Length; i++) | |
sb.Append(array[i]); | |
Console.WriteLine(sb.ToString()); | |
} | |
static void AskBool(string subject, ref bool test) | |
{ | |
Console.Write("Would you like to use {0}? (y|n): ", subject); | |
ConsoleKeyInfo key = Console.ReadKey(true); | |
while (key.Key != ConsoleKey.Y && key.Key != ConsoleKey.N) | |
key = Console.ReadKey(true); | |
Console.WriteLine(key.Key); | |
test = key.Key == ConsoleKey.Y; | |
} | |
static void AskInt(string question, ref int response, int lower, int upper) | |
{ | |
if (upper > lower) // Make sure a coder hooking into this library doesn't accidently create an infinite loop. Defensive coding! | |
{ | |
Console.WriteLine("\n{0}? (Valid Range: {1}-{2})", question, lower, upper); | |
while (!Int32.TryParse(Console.ReadLine(), out response) || response > upper || response < lower) | |
{ | |
Console.WriteLine("That input didn't make sense. Please type a numeric value between {0} and {1}.", lower, upper); | |
} | |
} | |
else | |
throw new Exception("AskInt requires that your upper bound be higher than your lower bound."); | |
} | |
static void generatePassword(bool ASCII, bool upper, bool lower, bool num, bool sym, int length, int numOfPass) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
Random r = new Random(); | |
int RandomLength = 0; | |
char[] charset; | |
if (length > 0 && length < 33 && (ASCII || upper || lower || num || sym)) // Length should never be either of these values, but this is good defensive coding. You never know when someone else might mess up your main method. | |
{ | |
for (int j = 0; j < numOfPass; j++) | |
{ | |
if (ASCII) | |
{ | |
RandomLength = 255; | |
for (int i = 0; i < length; i++) | |
{ | |
sb.Append((char)(r.Next(RandomLength)+1)); // 0 is NULL terminator, and not alt-able. 255 total values, 1-255. | |
} | |
} | |
else | |
{ | |
RandomLength = 0; | |
RandomLength += upper ? ALPHA.Length : 0; | |
RandomLength += lower ? alpha.Length : 0; | |
RandomLength += num ? numeric.Length : 0; | |
RandomLength += sym ? symbol.Length : 0; | |
charset = new char[RandomLength]; | |
int curLength = 0; | |
BuildCharset(upper, ref curLength, ref charset, ref ALPHA); | |
BuildCharset(lower, ref curLength, ref charset, ref alpha); | |
BuildCharset(num, ref curLength, ref charset, ref numeric); | |
BuildCharset(sym, ref curLength, ref charset, ref symbol); | |
for (int i = 0; i < length; i++) | |
{ | |
int pos = r.Next(RandomLength); | |
sb.Append(charset[pos]); | |
} | |
} | |
Console.WriteLine("\nYour generated password is: {0}", ASCII ? KeyCombo(sb.ToString()) : sb.ToString()); | |
if (!ASCII) | |
Console.WriteLine(KeyCombo(sb.ToString())); | |
sb.Clear(); | |
} | |
double stats = Math.Pow((double)RandomLength, (double)length); | |
double result1 = Math.Ceiling(stats / 1000); | |
double result2 = Math.Ceiling(stats / 10000000); | |
double result3 = Math.Ceiling(stats / 100000000000); | |
string unit1 = ""; | |
string unit2 = ""; | |
string unit3 = ""; | |
FriendlyUnits(ref result1, ref unit1); | |
FriendlyUnits(ref result2, ref unit2); | |
FriendlyUnits(ref result3, ref unit3); | |
Console.WriteLine("\nPassword Statistics:"); | |
Console.WriteLine("---------------------"); | |
if (stats < Int64.MaxValue) | |
Console.WriteLine("\nYour password's uniqueness is 1 in {0:N0}", stats); | |
else | |
Console.WriteLine("\nYour password's uniqueness is 1 in {0}", stats); | |
if (result1 < 100) | |
Console.WriteLine("At 1,000 guesses per second it would take\t{0:N1}\t{1} to guess.", result1, unit1); | |
else | |
Console.WriteLine("At 1,000 guesses per second it would take:\n{0:F1} {1} to guess.", result1, unit1); | |
if (result2 < 100) | |
Console.WriteLine("At 10,000,000 guesses per second it would take\t{0:N1}\t{1} to guess.", result2, unit2); | |
else | |
Console.WriteLine("At 10,000,000 guesses per second it would take:\n{0:F1} {1} to guess.", result2, unit2); | |
if (result3 < 100) | |
Console.WriteLine("At 100 Billion guesses per second it would take\t{0:N1}\t{1} to guess.\n", result3, unit3); | |
else | |
Console.WriteLine("At 100 Billion guesses per second it would take:\n{0:F1} {1} to guess.\n", result3, unit3); | |
} | |
else | |
{ | |
Console.WriteLine("\nNo valid passwords could be generated. Check your criteria, and try again.\n"); | |
} | |
} | |
static string KeyCombo (string password) | |
{ | |
StringBuilder sb = new StringBuilder(80); | |
for (int i = 0; i < password.Length; i++ ) | |
{ | |
char c = password.Substring(i, 1).ToCharArray()[0]; | |
int k = keyboard.IndexOf(c); | |
int K = KEYBOARD.IndexOf(c); | |
if (k > 0) | |
sb.Append(string.Format("{0} ", keyboard.Substring(k, 1).ToUpper())); | |
else if (K > 0) | |
sb.Append(string.Format("Shift+{0} ", keyboard.Substring(K, 1).ToUpper())); | |
else if (c == ' ') | |
sb.Append("Spacebar "); | |
else | |
sb.Append(string.Format("Alt+{0} ", (byte)c)); | |
} | |
return sb.ToString(); | |
} | |
static void FriendlyUnits (ref double d, ref string unit) | |
{ | |
double result = d; | |
int i = 0; | |
// This code might never run if the result is already within range. | |
while (result >= 1 && i < units.Length - 1) | |
{ | |
i++; | |
result = result / unitValues[i]; | |
if (result >= 1) // only assign the result if it's in the right range | |
d = result; | |
else // This is the final run of the loop, because the result is too coarse. Reduce i so that the appropriate unit is selected. | |
i--; | |
} | |
unit = units[i]; | |
} | |
static void BuildCharset (bool test, ref int curLength, ref char[] charset, ref char[] chars) | |
{ | |
if (test) | |
{ | |
chars.CopyTo(charset, curLength); | |
curLength += chars.Length; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment