验证 Membership.GeneratePassword

Posted

技术标签:

【中文标题】验证 Membership.GeneratePassword【英文标题】:Validating Membership.GeneratePassword 【发布时间】:2019-09-19 00:36:24 【问题描述】:

我正在使用 Membership.GeneratePassword() 来生成随机密码。有时返回的值与所需的验证要求不匹配。用户还可以提供密码,因此需要验证。

我基本上是想检查返回的密码,如果它不包含大写字母,小写字母和数字,则生成另一个。

有时我的支票会返回真,但显然不是。

我已经尝试过 RegEx 和一些 LINQ:

string generatePassword()

    password =  System.Web.Security.Membership.GeneratePassword(16, 8);

    if (password.Any(c => char.IsUpper(c)) && password.Any(c => char.IsDigit(c)) && password.Any(c => char.IsLower(c)))
    
        return password;
    
    else
    
       generatePassword();
    



void test() 
    var pattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*()_\-+=[\];:<>|.\/\?])(?=.8,)";

    var count = 0;
    for (var i = 0; i < 10000; i++)
    
        var password = generatePassword();
        if (!Regex.Match(password, pattern).Success)
        
             Console.WriteLine(password);
             count++;
        
    

    Console.WriteLine("There were 0 non matches", count);

在我看来,上面应该总是返回一个有效的密码。我有一个奇怪的场景,它会返回一个没有数字的密码,所以检查失败,但是如果我在test 内对返回的密码执行相同的passowrd.Any(char.IsDigit),它会说是真的。

如果有帮助,密码至少需要 8 位,包含大写、小写、数字和特殊字符:!@#$%^&amp;*()_-+=[];:&lt;&gt;|./?

谢谢。

【问题讨论】:

查看这个答案:***.com/a/43085890/6844481 【参考方案1】:

也许您的正则表达式是有效的,但我认为很难理解它的作用。

考虑使用下面的代码,它的优点是它只会枚举您的密码,直到它检测到它是有效的。另外它易于理解,易于进行小改动,例如大小至少应为 12 个字符,或者不再必须有大写字符,或者它应该包含两个数字,...

我会将它编程为字符串的扩展方法。如果您决定您的密码不再是字符串,那么更改将是最小的。见extension methods demystified

static bool IsSpecialChar(this char c)

    const string specialChars = "!@#$%^&*()_-+=[];:<>|./?";
    return specialChars.Contains(c);


static bool IsValidPassword(this string password)

    // the password needs to be at least 8 characters,
    // contain an uppercase, lowercase, digit and a special char

    // TODO: exception if password == null;
    if (password.Length < 8) return false;

    bool uppercaseDetected = false;
    bool lowercaseDetected = false;
    bool digitDetected = false;
    bool specialCharDetected = false;

    using (IEnumerator<char> enumerator = password.GetEnumerator())
    
        while (enumerator.MoveNext
           && !(uppercaseDetected && lowercaseDetected 
                 && digitDetected && specialCharDetected))
        
            // a character is available, and we still don't know if it is a proper password
            char c = enumerator.Current;
            uppercaseDetected = uppercaseDetected || Char.IsUpperCase(c);
            lowercaseDetected = lowercaseDetected || Char.IsLowerCase(c);
            digitDetected = digitDetected || Char.IsDigit(c);
            specialCharDetected = specialCharDetected || c.IsSpecialChar();
        

        return uppercaseDetected && lowercaseDetected 
            && digitDetected && specialCharDetected;
    

用法:

string GeneratePassword()

    string proposedPassword = ...;
    while (!proposedPassword.IsValidPassword())
    
        proposedPassword = ...;
    

为确保结束,您可以添加一个计数器,并在 1000 次尝试后停止;或者只是添加一个随机的大写/小写/特殊字符

【讨论】:

以上是关于验证 Membership.GeneratePassword的主要内容,如果未能解决你的问题,请参考以下文章

tp5.1 验证规则 验证数字

js实现输入手机验证码后点击提交按钮验证手机输入的验证码和发送的验证码是不是一致

原生JavaScript判断是否为邮箱危险字符验证长度验证网址验证小数整数浮点数等常用的验证

Java如何实现验证码验证功能

facebook怎么验证?

[8期]浅谈当代安全验证问题