在用戶管理時, 總有須要重設密碼, 若密碼設定太簡單(e.g. 123456), 用戶不去改便容易有保安漏洞, 所以寫了個PasswordGenerator class, 以singleton 形式去產生password. 為了更方便設定, 亦加入了password complexity 相關設定(最少10個字, 英文字母大小楷, 包括符號), 提供更大的彈性.
PasswordGeneratorCondition.cs
public class PasswordGeneratorCondition
{
public int UppercaseCount { get; set; }
public int LowercaseCount { get; set; }
public int AlphanCharacterCount { get; set; }
public int DigitCount { get; set; }
public PasswordGeneratorCondition()
{
this.UppercaseCount = 2;
this.LowercaseCount = 3;
this.AlphanCharacterCount = 3;
this.DigitCount = 2;
}
}
PasswordGenerator.cs
public static class PasswordGenerator
{
private const string LOWERCASE_CHARACTERS = "abcdefghijklmnopqrstuvwxyz";
private const string UPPERCASE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private const string DIGIT_CHARACTERS = "1234567890";
private const string ALPHAN_CHARACTERS = @"~!@#$%^&*_-+=`|\(){}[]:;""'<>,.?/";
public static string Generate(PasswordGeneratorCondition condition = null)
{
if (condition == null)
condition = new PasswordGeneratorCondition();
string value = "";
value += condition.LowercaseCount>0 ? GetRandomString(condition.LowercaseCount, LOWERCASE_CHARACTERS) : "";
value += condition.UppercaseCount > 0 ? GetRandomString(condition.UppercaseCount, UPPERCASE_CHARACTERS) : "";
value += condition.AlphanCharacterCount > 0 ? GetRandomString(condition.AlphanCharacterCount, ALPHAN_CHARACTERS) : "";
value += condition.DigitCount > 0 ? GetRandomString(condition.DigitCount, DIGIT_CHARACTERS) : "";
return value.Shuffle();
}
private static string GetRandomString(int length, string charactors)
{
StringBuilder res = new StringBuilder();
Random rnd = new Random(Guid.NewGuid().GetHashCode());
while (0 < length--)
{
res.Append(charactors[rnd.Next(charactors.Length)]);
}
return res.ToString();
}
private static string Shuffle(this string input)
{
char[] source = input.ToArray();
int cnt = source.Length;
Random rnd = new Random(Guid.NewGuid().GetHashCode());
while (cnt > 1) {
cnt--;
int k = rnd.Next(cnt+1);
char temp = source[k];
source[k] = source[cnt];
source[cnt] = temp;
}
return new string(source);
}
}
用一個console app 做示範, 如何叫用:
class Program
{
static void Main(string[] args)
{
string password = PasswordGenerator.Generate();
System.Console.WriteLine("Generated Password: "+password);
System.Console.WriteLine("Length: " + password.Length);
ConsoleKeyInfo Key=System.Console.ReadKey();
}
}
當然, 若果沒啥特別的話, 直接利用.net 都可以直接產生.
return System.Web.Security.Membership.GeneratePassword(<<length>>, <<No. of alpher characters required>>);
Reference
- Passwords must meet complexity requirements, Microsoft TechNet
- Fisher–Yates shuffle, Wikipedia
Leave a Reply