【问题标题】:Regex for complex password validation用于复杂密码验证的正则表达式
【发布时间】:2013-06-01 11:23:45
【问题描述】:

我在 stackoverflow 等上环顾四周,但没有找到一个好的答案。正则表达式是否支持编写这样的规则?如果是这样,我们那里有任何正则表达式专家可以帮助我写这篇文章,我是正则表达式的大新手,而且在时间紧迫的情况下......

我知道我可以使用 c# char, number 方法在 c# 中使用手动函数来执行此操作,但如果可以的话,我想使用正则表达式..

要求:

  • 至少 8 个字符长
    • 2 个字母
    • 2 位数
    • 1 大写
    • 1 小写
    • 1 个符号

【问题讨论】:

  • 如果这些是你要使用的实际规则,我讨厌你。 :)
  • 这些规则不是我编的:)
  • 正好 8 个字符或至少 8 个字符?
  • @MikeChristensen 不要忘记象形文字。
  • 正则表达式太复杂了。

标签: c# regex passwords


【解决方案1】:

你可以试试这个方法。

 private bool ValidatePassword(string password, out string ErrorMessage)
{
    var input = password;
    ErrorMessage = string.Empty;

    if (string.IsNullOrWhiteSpace(input))
    {
        throw new Exception("Password should not be empty");
    }

    var hasNumber = new Regex(@"[0-9]+");
    var hasUpperChar = new Regex(@"[A-Z]+");
    var hasMiniMaxChars = new Regex(@".{8,8}");
    var hasLowerChar = new Regex(@"[a-z]+");
    var hasSymbols = new Regex(@"[!@#$%^&*()_+=\[{\]};:<>|./?,-]");

    if (!hasLowerChar.IsMatch(input))
    {
        ErrorMessage = "Password should contain At least one lower case letter";
        return false;
    }
    else if (!hasUpperChar.IsMatch(input))
    {
        ErrorMessage = "Password should contain At least one upper case letter";
        return false;
    }
    else if (!hasMiniMaxChars.IsMatch(input))
    {
        ErrorMessage = "Password should not be less than or greater than 8 characters";
        return false;
    }
    else if (!hasNumber.IsMatch(input))
    {
        ErrorMessage = "Password should contain At least one numeric value";
        return false;
    }

    else if (!hasSymbols.IsMatch(input))
    {
        ErrorMessage = "Password should contain At least one special case characters";
        return false;
    }
    else
    {
        return true;
    }
}

【讨论】:

  • 我更喜欢这种方法。谢谢
  • @Najeeb 谢谢
  • -1 :这不符合可访问性标准 - 所有错误消息都应在单个响应中返回。此方法可能会导致多次尝试相同的输入,但错误响应不同。应该重构它以测试所有规则并返回错误集合
【解决方案2】:

你可以使用这个正则表达式

^(?=(.*\d){2})(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z\d]).{8,}$
    ---------  --------------------- --------------- -----
        |               |                    |          |->match 8 or more characters
        |               |                    |->match further only if theres anything except letter or digit
        |               |->match further only if there is an upper-lower case letter
        |
        |->match further only if there are two digits anywhere

Demo

【讨论】:

  • @Anirudh - 啊编辑后,它现在可以工作了.. 我不会使用它,但 +1 一起破解它。
  • +1,永远不知道正则表达式中有(?=这样的东西。伟大的工作。
  • 我会测试一下,如果它通过了我的验证测试,则将其标记为答案。谢谢。
  • @kyleb - 这样做的一个缺点是你不能告诉用户为什么他们的密码无效,你只能告诉他们不是。
  • 是的,我不能告诉他们哪里出了问题,但这不是现在的要求。如果它确实成为一个,我将改用 C#。
【解决方案3】:

我建议采用 Oded 的回答方式,但我认为 LINQ 在这种情况下是一种更具可读性和更明确的验证机制。

string p = "psW%Rd32";
return p.Length >= 8 &&
    p.Count(c => char.IsDigit(c)) >= 2 &&
    p.Count(c => char.IsUpper(c)) >= 1 &&
    p.Count(c => char.IsLower(c)) >= 1) ...

【讨论】:

  • 虽然我喜欢它,但您 正在 对字符串进行多次迭代(每个 Count 一次)。
  • return p.Length == 8 是错误的。您必须至少有 8 个字符
  • +1 - 虽然它需要对字符串进行多次迭代,但它易于阅读且组织良好。
  • 我知道你会选择性能。 :) 我认为这是为了实时验证文本框,而不是在事后迭代数千个密码。在这种情况下,我们实际上迭代的字符不超过 1-2 打,过去 15 年的任何 CPU 都不会感受到任何性能优势。
  • @Damith 取决于 OP 想要强制执行什么,这只是一个示例。
【解决方案4】:

您最好为具有所有这些检查的密码编写一个简单的验证例程。

对于这个特定问题,正则表达式似乎不是最好的(或最可扩展的)解决方案。

if(password.Length < 8)
  return false;

var letters = 0;
var digits = 0;
var uppers = 0;
var lowers = 0;
var symbols = 0;
foreach(var ch in password)
{
   if (char.IsLetter(ch)) letters++;
   if (char.IsDigit(ch)) digits++;
   ....
} 

if(letters < 2) return false;
...

【讨论】:

  • 虽然可以使用正则表达式,但这是一种更易于维护的解决方案。
  • 我倾向于这个,但我想看看是否有人可以先创建这样的正则表达式..
  • +1,很好,可以想象,更易于维护,与 long-long 正则表达式相比。
  • @kyleb,我也在尝试,但从我的图片来看,它太长了。
猜你喜欢
  • 2016-10-09
  • 2011-07-10
  • 1970-01-01
  • 2014-10-14
  • 2023-03-12
  • 2011-04-17
  • 2018-03-16
  • 1970-01-01
相关资源
最近更新 更多