- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想在 C# 中使用正则表达式验证密码。
这些是条件:
这是我的尝试:
^(?=.*[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/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!