gpt4 book ai didi

c# - 密码验证的正则表达式 C#

转载 作者:太空宇宙 更新时间:2023-11-03 20:08:05 27 4
gpt4 key购买 nike

我想在 C# 中使用正则表达式验证密码。

这些是条件:

  1. 不应以数字或特殊字符开头
  2. 不应以特殊字符结尾
  3. 必须至少包含这三个字符中的任何一个('@'、'#'、'_')并且不允许使用其他特殊字符。
  4. 必须至少包含一个字母
  5. 必须至少包含一位数字
  6. 长度应至少为 8 个字符

这是我的尝试:

^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#_])

我知道满足上述条件还差得很远。所以请任何人修改这个正则表达式,使其满足上述所有条件。

提前致谢。

最佳答案

其他人已经为您建议了正则表达式的答案,也许这是您问题的不可动摇的约束。但是,这段 C# 可以满足您的要求,并且与正则表达式的不同之处在于它的可读性要高得多。我希望初级程序员能够阅读和理解它(而且修改它也更容易,比如说,不返回 false 但成功时返回 null 和一个描述密码失败的字符串)。它还在 O(n) 中运行(考虑到您的典型密码将是 << 100 个字符,这是一件小事。

private const int kMinimumLength = 8;
private static string _specialChars = "@#_";
private static bool IsSpecialChar(char c) { return _specialChars.IndexOf(c) >= 0; }
private static bool IsValidPasswordChar(char c) { return IsSpecialChar(c) || Char.IsLetterOrDigit(c); }

public static bool IsPasswordValid(string password)
{
if (password == null || password.Length < kMinimumLength || IsSpecial(password[0])
|| IsSpecial(password[password.Length - 1]))
return false;
bool hasLetter = false, hasDigit = false;
int specials = 0;
foreach (char c in password)
{
hasDigit = hasDigit || Char.IsDigit(c);
hasLetter = hasLetter || Char.IsLetter(c);
specials += IsSpecialChar(c) ? 1 : 0;
if (!IsValidPasswordChar(c)) return false;
}
return hasDigit && hasLetter && specials > 1;
}

现在,如果您考虑这个过程并了解在如此小的问题域中,您可能会更好地执行以下操作以提高可读性:

public class Rule {
public Func<string, bool> Predicate { get; set; }
public string Description { get; set; }
}

private List<Rule> rules = new List<Rule>() {
new Rule(){ Predicate = (s => s != null),
Description = "Password must not be null" },
new Rule(){ Predicate = (s => s.Length >= kMinimumLength ),
Description = "Password must have at least " + kMinimumLength + " characters." },
new Rule(){ Predicate = (s => s.Count(c => IsSpecialChar(c)) >= 1),
Description = "Password must contain at least one of " + _specialChars },
new Rule(){ Predicate = (s => !IsSpecialChar(s[0]) && !IsSpecialChar(s[s.Length - 1])),
Description = "Password must not start or end with " + _specialChars },
new Rule(){ Predicate = (s => s.Count(c => Char.IsLetter(c)) > 0),
Description = "Password must contain at least one letter." },
new Rule(){ Predicate = (s => s.Count(c => Char.IsDigit(c)) > 0),
Description = "Password must contain at least one digit." },
new Rule(){ Predicate = (s =>s.Count(c => !IsValidPasswordChar(c)) == 0),
Description = "Password must contain letters, digits, or one of " + _specialChars }
}

public bool IsPasswordValid(string s, ref string failureReason)
{
foreach (Rule r in rules) {
if (!r.Predicate(s)) {
failureReason = r.Description;
return false;
}
}
return true;
}

在您开始认为我已经对您进行了全面测试之前,您可以立即查看这段代码,每条规则都是自记录的。很容易修改。易于维护。所有规则都是相互隔离的,如果您选择对谓词使用静态方法而不是 lambda,您可以轻松地对每个规则单独进行单元测试。

运行这段代码:

    static void Main(string[] args)
{
string reason = null;
if (!IsPasswordValid(null, ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("aaaaaaaa", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("_aaaaaaa", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("aaaaaaa_", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("1aaa!aaa", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("11111111", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("a1a1a1a1", ref reason)) Console.WriteLine(reason);
if (!IsPasswordValid("a1a1@1a1", ref reason)) Console.WriteLine(reason);

StringBuilder sb = new StringBuilder();
sb.Append('a');
for (int i = 0; i < 1000000; i++) { sb.Append('@'); }
sb.Append('a');
sb.Append('1');
string pass = sb.ToString();
long ticks = Environment.TickCount;
if (IsPasswordValid(pass, ref reason)) Console.WriteLine("Valid.");
long endticks = Environment.TickCount;
Console.WriteLine("Time elapsed: " + (endticks - ticks));
}

给出:

Password must not be null
Password must have at least 8 characters.
Password must contain at least one of @#_
Password must not start or end with @#_
Password must not start or end with @#_
Password must contain at least one of @#_
Password must contain at least one of @#_
Password must contain at least one of @#_
Valid.
Time elapsed: 62

因此,如果您担心性能,它可以在 62 毫秒内检查 1Mb 的密码(在我的机器上,这非常强大)。

tl;dr - “有些人在遇到问题时会想“我知道,我会使用正则表达式。”现在他们有两个问题。” - Jamie Zawinksi

关于c# - 密码验证的正则表达式 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21760692/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com