Генератор пароля в котором по очереди встречаются буквы и цифры
string pass1 = "123456789";
string pass2 = "QWERTYUIOPASDFGHJKLZXCVBNM";
Как сделать генерацию паролей определенной длины из заданных чисел и символов? Что бы они шли друг за другом, буква > число.
Что бы сделать примерно такой вывод: Q2S4F9R3K2J8E1
Использовать Random rnd = new Random(0);?
Ответы (5 шт):
Написал топорное, но простое и понятное решение:
// строки, содержащие нужные символы
static string numbers = "123456789";
static string letters = "QWERTYUIOPASDFGHJKLZXCVBNM";
static char generate_random_letter() {
return letters[rnd.Next(letters.Length)];
}
static char generate_random_number() {
return numbers[rnd.Next(numbers.Length)];
}
public static void Main (string[] args) {
int password_length = 10;
string password = "";
for (int i = 0; i < password_length; i++) {
if (i % 2 == 0) {
password += generate_random_letter();
}
else {
password += generate_random_number();
}
}
Console.WriteLine(password);
}
Случайно переставить элементы pass1 и pass2 (см. тут или тут) потом использовать linq'шный Zip и обрезать при помощи .Take с нужным количеством символов.
Например:
void Main()
{
string pass1 = "123456789";
string pass2 = "QWERTYUIOPASDFGHJKLZXCVBNM";
this.GenPass(pass1.Shuffle(), pass2.Shuffle(), 10).Dump();
}
public string GenPass(string pass1, string pass2, int maxChar)
{
var result = pass1.Zip(pass2, (x, y) => $"{x}{y}");
//result.Dump();
var joined = string.Join("", result).Take(maxChar);
return new string(joined.ToArray());
}
public static class Ext1
{
public static string Shuffle(this string str)
{
char[] array = str.ToCharArray();
Random rng = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
var value = array[k];
array[k] = array[n];
array[n] = value;
}
return new string(array);
}
}
Возможно, есть что улучшить, просто решил задачу "в лоб".
Пример ниже ограничен 18-ю символами (можно расширить).
static String GetRandomPass(Int32 length) {
if (length > 18) return null;
Random r = new Random();
String p = String.Join("",
Enumerable.Range(65, 26).OrderBy(a => r.Next()).Zip(
Enumerable.Range(49, 9).OrderBy(b => r.Next()),
(x, y) => new String(new Char[]{(Char)x, (Char)y})
).ToArray());
return p.Substring(0, length);
}
Все мы знаем что в таких вопросах не нужен красивый, правильный и удобочитаемый код. Нужен однострочник на LINQ, который можно бездумно скопировать себе в код и сразу отправить в production.
Собственно, вот он:
int length = 12; // длина
var random = new Random();
var result = string.Join("",Enumerable.Range(0, length).Select(i => i%2==0 ? (char)('A'+random.Next(26))+"" : random.Next(1, 10)+""));
Ну или то же самое с разъяснениями:
var result = string.Join("", // создаем строку
Enumerable.Range(0, length) // из последовательности длины length
.Select(i =>
i%2==0 ? // на четных местах
(char)('A'+random.Next(26))+"" : // генерируем букву
random.Next(1, 10)+"") // на нечетных цифру
);
Использовать
Random rnd = new Random(0);?
Random использовать нужно, но при этом обязательно использовать пустой конструктор. Конструктор, который принимает число, (Random (int Seed)) использует это число как начальное состояние. Такой Random всегда будет выдавать одну и ту же последовательность чисел.
P.S. pass1 и pass2 не использовал, вместо этого генерирую заглавные буквы английского алфавита и цифры от 1 до 9 (Почему 0 не используется, кстати?).
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
namespace Rextester
{
public enum PasswordWeakLevel
{
NotDefined,
VeryWeak,
Weak,
Sufficient,
Strength,
Resistant,
VeryResistant
}
public static class PasswordUtils
{
private static int MaxRepeatsChar = 2;
public static string GenerateStrongPass(int PassLength = 7, bool UsePunctuation = true, bool UseEntropy = true, int CheckDigits = 0)
{
int checkSum = 0;
Random randC = new Random();
string result = char.ToString((char)randC.Next(65, 90));
List<char[]> Intrvs = new List<char[]>();
char[] charr;
if (UsePunctuation)
{
string specChars = @"!#$%&*+-/=?@\^_|~"; //@"!#$%&()*+-/;<=>?@[\]^_{|}~";
charr = specChars.ToCharArray();
Intrvs.Add(charr);
}
string gl = "AaEeIiOoUu";
charr = gl.ToCharArray();
Intrvs.Add(charr);
string sl = "BbCcDdFfGgHhJjKkLMmNnPpQqRrSsTtVvWwXxYyZz";
charr = sl.ToCharArray();
Intrvs.Add(charr);
string dl = "189647235";
charr = dl.ToCharArray();
Intrvs.Add(charr);
Random randI = new Random();
while (result.Length < PassLength)
{
int rndIndex = randI.Next(Intrvs.Count);
int charIndex = randC.Next(Intrvs[rndIndex].Length);
string C = char.ToString(Intrvs[rndIndex][charIndex]);
if (!result.Contains(C) && (result.Length < 35))
{
result += C;
}
else
if (!UseEntropy)
{
result += C;
}
}
if (CheckDigits > 0)
{
int i = 1;
int last = 719;
foreach (var c in result)
{
checkSum += (Convert.ToInt32(c) * i) + last;
i++;
last = Convert.ToInt32(c);
}
string hex = ((checkSum / Convert.ToInt32(result[0])) * 2).ToString("X2") + checkSum.ToString("x2");
int checkCounts = hex.Length;
result += hex.Substring(hex.Length - CheckDigits, Math.Min(CheckDigits, checkCounts));
}
return result;
}
public static PasswordWeakLevel TestPasswordWeak(string password, string login)
{
var _res = PasswordWeakLevel.NotDefined;
if (!IsPasswordLikeLogin(password, login) && !IsQwertyPasswords(password))
{
if (password.Length > 5)
{
if (ContainsUpperLetter(password) && ContainsLowerLetter(password)) _res = PasswordWeakLevel.Weak;
if (ContainsDigit(password)) _res++; //Sufficient
if (RepeatSigns(password)) _res--;
if (IsStriping(password)) _res++; //Strength
if (ContainsPunctuation(password) && ContainsSeparator(password)) _res++; //Resistant
if ((_res == PasswordWeakLevel.Resistant) && (password.Length > 15)) _res++;
}
else
_res = PasswordWeakLevel.VeryWeak;
}
return _res;
}
private static bool IsQwertyPasswords(string pass)
{
var keyboardlist = new List<string>();
keyboardlist.Add("azer");
keyboardlist.Add("qwer");
keyboardlist.Add("asdf");
keyboardlist.Add("zxcv");
keyboardlist.Add("1234");
foreach (string item in keyboardlist)
{
if (pass.ToLower().Trim().Contains(item.ToLower()))
return true;
}
return false;
}
private static bool IsPasswordLikeLogin(string pass, string login)
{
if (login != string.Empty)
{
if (login.ToLower().Trim().Contains(pass.ToLower().Trim()) || pass.ToLower().Trim().Contains(login.ToLower().Trim()))
{
return true;
}
string reversed = "";
char[] passarr = pass.ToCharArray();
for (int i = pass.Length - 1; i >= 0; i--)
{
reversed = reversed + passarr[i];
}
if (reversed.ToLower().Trim().Contains(login.ToLower().Trim()))
{
return true;
}
}
return false;
}
private static bool RepeatSigns(string pass)
{
char lastchar = (char)0;
int _rep = 0;
foreach (char c in pass)
{
if (lastchar == c)
{
_rep++;
if (_rep > MaxRepeatsChar)
return true;
}
lastchar = c;
}
return false;
}
private static bool IsStriping(string pass) // фактор перемеживание букв и символов
{
int stripcount = 0;
char lastchar = (char)0;
foreach (char c in pass)
{
if ((Char.IsLetterOrDigit(c) && ((Char.IsLetter(c) && Char.IsDigit(lastchar)) || (Char.IsDigit(c) && Char.IsLetter(lastchar)))) ||
((Char.IsLetterOrDigit(c) && !Char.IsLetterOrDigit(lastchar)) || ((Char.IsLetterOrDigit(lastchar) && !Char.IsLetterOrDigit(c)))))
{
stripcount++;
if (stripcount > pass.Length / 3)
return true;
}
lastchar = c;
}
return false;
}
private static bool ContainsLowerLetter(string pass)
{
foreach (char c in pass)
{
if ((Char.IsLetter(c)) && (Char.IsLower(c)))
return true;
}
return false;
}
private static bool ContainsUpperLetter(string pass)
{
foreach (char c in pass)
{
if ((Char.IsLetter(c)) && (Char.IsUpper(c)))
return true;
}
return false;
}
private static bool ContainsDigit(string pass)
{
foreach (char c in pass)
{
if (Char.IsDigit(c))
return true;
}
return false;
}
private static bool ContainsPunctuation(string pass)
{
foreach (char c in pass)
{
if (Char.IsPunctuation(c))
return true;
}
return false;
}
private static bool ContainsSeparator(string pass)
{
foreach (char c in pass)
{
if (Char.IsSeparator(c))
return true;
}
return false;
}
public static bool BadPasswordSecurity(string pass, string Login)
{
return ((int)PasswordUtils.TestPasswordWeak(pass, Login) < 5);
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static void Main(string[] args)
{
for(int i = 0; i< 100; i++)
{
string pass = PasswordUtils.GenerateStrongPass(11, true, true, 0);
Console.WriteLine(pass);
Thread.Sleep(100);
}
}
}
}