在用戶管理時, 總有須要重設密碼, 若密碼設定太簡單(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