Gerador de senha “Crapcode”
Fiz o Gerador de senha em C #.
Ele solicita ao usuário o comprimento da senha , se contém números , letras minúsculas , letras maiúsculas ou símbolos , e gera uma senha forte a partir de números, letras ou símbolos adicionados aleatoriamente.
Aqui está o código:
using System;
namespace Password_Generator
{
class Program
{
static string Randomize(string Str)
{
Random Rand = new Random();
string Randomized = "";
while (Randomized.Length < Str.Length)
{
Randomized += Str[Rand.Next(0, Str.Length)];
}
return Randomized;
}
static void Main(string[] args)
{
while (true)
{
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nDo Yout Want a New Password [True], [False]? ");
Console.ForegroundColor = ConsoleColor.Yellow;
string NewPasswordStr = Console.ReadLine();
bool NewPassword;
while (bool.TryParse(NewPasswordStr, out NewPassword) == false)
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("The Given Output is Unconvertable Or it's Value is Unacceptable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nDo Yout Want a New Password [True], [False]? ");
Console.ForegroundColor = ConsoleColor.Yellow;
NewPasswordStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.ForegroundColor = ConsoleColor.White;
if (NewPassword == true)
{
Console.Clear();
Console.Write("Password Length: ");
Console.ForegroundColor = ConsoleColor.Yellow;
string LenghtStr = Console.ReadLine();
int Lenght;
while (int.TryParse(LenghtStr, out Lenght) == false || int.Parse(LenghtStr) <= 0)
{
Console.Clear();
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("The Given Output is Unconvertable Or it's Value is Unacceptable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nPassword Length: ");
Console.ForegroundColor = ConsoleColor.Yellow;
LenghtStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\n\nInclude Numbers (0 - 9) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
string IncludeNumbersStr = Console.ReadLine();
bool IncludeNumbers;
while (bool.TryParse(IncludeNumbersStr, out IncludeNumbers) == false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nInclude Numbers (0 - 9) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
IncludeNumbersStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.Write("\n\nInclude Lowercase Letters (a - z) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
string IncludeLowercaseStr = Console.ReadLine();
bool IncludeLowercase;
while (bool.TryParse(IncludeLowercaseStr, out IncludeLowercase) == false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nInclude Lowercase Letters (a - z) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
IncludeLowercaseStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\n\nInclude Uppercase Letters (A - Z) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
string IncludeUppercaseStr = Console.ReadLine();
bool IncludeUppercase;
while (bool.TryParse(IncludeUppercaseStr, out IncludeUppercase) == false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nInclude Uppercase Letters (A - X) [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
IncludeUppercaseStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\n\nInclude Symbols [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
string IncludeSymbolsStr = Console.ReadLine();
bool IncludeSymbols;
while (bool.TryParse(IncludeSymbolsStr, out IncludeSymbols) == false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\nThe Given Output is Unconvertable. Try Again!");
Console.ForegroundColor = ConsoleColor.White;
Console.Write("\nInclude Symbols [True], [False]: ");
Console.ForegroundColor = ConsoleColor.Yellow;
IncludeSymbolsStr = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
}
Console.ForegroundColor = ConsoleColor.White;
string Password = "";
while (Password.Length < Lenght)
{
Random Rand = new Random();
if (IncludeNumbers == true)
{
Password += ((char)Rand.Next(48, 58)).ToString();
}
if (Password.Length == Lenght)
{
break;
}
if (IncludeLowercase == true)
{
Password += ((char)Rand.Next(97, 123)).ToString();
}
if (Password.Length == Lenght)
{
break;
}
if (IncludeUppercase == true)
{
Password += ((char)Rand.Next(97, 123)).ToString().ToUpper();
}
if (Password.Length == Lenght)
{
break;
}
if (IncludeSymbols == true)
{
Password += ((char)Rand.Next(33, 48)).ToString().ToUpper();
}
if (Password.Length == Lenght)
{
break;
}
}
Password = Randomize(Password);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine(Password);
Console.ForegroundColor = ConsoleColor.White;
}
else
{
Environment.Exit(-1);
}
}
}
}
}
As linhas 221 são demais para isso? Como melhorar isso? Isso é um "crapcode"? Como não escrever crapcode? ....Obrigado!
Respostas
Da documentação da classe MSDN Random
Para gerar um número aleatório criptograficamente seguro, como um que seja adequado para criar uma senha aleatória, use a classe RNGCryptoServiceProvider ou derivar uma classe de System.Security.Cryptography.RandomNumberGenerator.
Rand aleatório = novo aleatório ();
Correção de edição : usando um instantâneo do relógio do sistema, o construtor sem parâmetro acaba usando valores de semente diferentes; a menos que os objetos aleatórios sejam criados tão próximos no tempo que o mesmo relógio seja usado. Dado o mesmo argumento (valor da semente do parâmetro), Randoms diferentes geram a mesma sequência aleatória. fim da edição
Cada
Randomobjeto criado com o construtor sem parâmetros irá gerar a mesma sequência de números aleatórios porque o mesmo valor de "semente padrão" é usado todas as vezes. Isso é perfeito para desenvolvimento e teste, mas não em código de produção. Ler a hora do sistema em milissegundos é uma maneira comum de gerar diferentes valores de "semente" para cada chamada do construtor.
Crapcode
Code Smell
As dúvidas vagas que você tem sobre o código são tecnicamente chamadas de "cheiro de código", o que significa que parece suspeito por algum motivo - o comprimento "parece" longo para o que está fazendo, neste caso. Pode haver algo errado, talvez não; um "cheiro de código" requer um exame mais minucioso para determinar se algo está de fato errado.
Um cheiro de código que vejo são os vários whileloops de aparência semelhante , cada um procurando por diferentes caracteres necessários. Não quero escrever código difícil de entender por causa de menos linhas. "Menos linhas de código" por si só não é razão para mudar as coisas. Aqui está uma ideia, talvez seja uma melhoria ou talvez não:
Informe ao usuário os caracteres obrigatórios antecipadamente ao solicitar a senha.
Uma string é iterável, você pode "forEach". A Stringé, na verdade, uma matriz de Char, tecnicamente.
forEach (char character in enteredPassword) { ... }
Examine cada personagem para seu tipo. Mantenha uma contagem separada para cada tipo de caractere.
Após o forEachteste de cada contador para o mínimo necessário. Se symbolsfor zero, por exemplo, acrescente "pelo menos um caractere de símbolo é necessário" a uma mensagem de erro.
Para sua informação
Há um velho ditado com um fundo de verdade: se você resolve um problema com uma expressão regular, agora você tem dois problemas
221 linhas são demais para isso
Existem muitas diretrizes, princípios, "ismos", etc. para avaliar a qualidade do código. A contagem de linhas não é um deles.