【问题标题】:Would this regular expression work?这个正则表达式会起作用吗?
【发布时间】:2010-11-05 10:06:38
【问题描述】:
^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{4,})$

这个正则表达式是否适用于这些规则?

  • 必须至少有 4 个字符
  • 字符可以是字母(大写/非大写)、数字和以下字符的混合:! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : '" , ? /

它旨在成为一个密码验证器。语言是 PHP。

【问题讨论】:

  • 如果您使用它来验证密码,我的问题是:为什么要限制他们可以使用的字符类型?您应该只需要检查最少的字符数
  • 而且 4 个字符对于任何值得保护的东西来说都太少了。如果不值得保护,为什么还要添加密码?
  • @MahlerFive 够吗?请注意,在针对数据库进行检查之前,密码将经过哈希处理+加盐处理。如果检查密码的字符数就足够了,那么我将不再实现这个正则表达式。 @Vinko 正如我在下面的评论中所说,我现在只使用了 4 个,因为它目前仍在开发中,登录时输入 4 个字符会更容易。
  • @Nikko:当您不指定字符范围并且用户在输入一些编码不同或根本不包含的字符时使用不同的编码时,您实际上可能会遇到问题(例如 UTF-8 和 ISO 8859-1)。但无论如何你都需要解决这个问题,而不是密码。
  • 您到底为什么要禁用特殊字符作为密码策略?我无法想象您会鼓励人们生成弱密码而不是强密码。

标签: php regex validation passwords


【解决方案1】:

没有。该正则表达式不适用于您声明的规则,原因很简单,$ 默认匹配 before 最后一个字符(如果它是换行符)。您允许使用“1234\n”之类的密码字符串。

解决方案很简单。要么使用\z 而不是$,要么将D 修饰符应用于正则表达式。

【讨论】:

    【解决方案2】:

    是吗?

    老实说,你要什么?为什么不测试一下?

    但是,如果您想要改进它的建议,请提出以下问题:

    1. 这个正则表达式检查什么?
    2. 为什么有这么多允许的字符集?
    3. 为什么不使用/\w/ 而不是/0-9a-zA-Z_/
    4. 为什么你在()s 有全部内容?您不需要捕获整个事物,因为您已经拥有了整个事物,并且不需要它们来对任何内容进行分组。

    我要做的是单独检查长度,然后对照正则表达式检查它是否有任何 bad 字符。您的好角色列表似乎足够大,这样做可能会更容易。但这可能取决于您这样做的目的。

    编辑:现在我知道这是以 PHP 为中心的,/\w/ 是安全的,因为 PHP 使用 PCRE 库,它不完全是 Perl,并且在 PCRE 中,\w匹配Unicode 字字符。因此,为什么不检查长度并确保没有无效字符:

    if(strlen($string) >= 4 && preg_match('[\s~\\]', $string) == 0) {
      # valid password
    }
    

    或者,使用很少使用的 POSIX 字符类 [[:graph:]]。它在 PHP 中的工作方式与在 Perl 中的工作方式几乎相同。 [[:graph:]] 匹配任何字母数字或标点字符,这听起来像你想要的,[[:^graph:]] 应该匹配相反的。测试是否所有字符都匹配图表:

    preg('^[[:graph:]]+$', $string) == 1
    

    测试是否有任何字符与图表不匹配:

    preg('[[:^graph:]]', $string) == 0
    

    【讨论】:

    • 我已经测试了正则表达式,但我只是想确保它是正确的,因为我不太擅长制作正则表达式(如您所见,我制作的正则表达式是'不是很优化)。基本上我在这里创建的是一个密码正则表达式,我需要的是一个不严格的正则表达式(不要求你有一个大写字母、一个特殊字符、一个数字等),但仍然有一个“好”字符的白名单。你能提供我的正则表达式的更好版本吗?
    • 你能解释一下 '[\s~\\]' 究竟检查了什么吗?
    • '\s' 匹配空格(空格和制表符),'\\' 匹配反斜杠(你必须用另一个反斜杠转义反斜杠),'~' 只是波浪号。跨度>
    【解决方案3】:

    您忘记了逗号 (,) 和句号 (.) 并添加了波浪号 (~) 和重音符 (`),这不是您的规范的一部分。此外,只需对字符集声明中的几个字符进行转义:

    ^([a-zA-Z0-9!@#$%^&*()|_\-+=[\]{}:;"',<.>?/~`]{4,})$
    

    作为preg_match 的 PHP 字符串声明:

    '/^([a-zA-Z0-9!@#$%^&*()|_\\-+=[\\]{}:;"\',<.>?\\/~`]{4,})$/'
    

    【讨论】:

    • 我已经编辑了原始引用的正则表达式以反映 , 和 . , 我在规范中添加了 ~ 和 `。
    【解决方案4】:

    您进行了额外的转义,并且没有使用某些预定义的字符类(例如 \w 或至少 \d)。

    除此之外,您在开头和结尾都锚定,这意味着正则表达式仅在字符串开始和结束匹配时才匹配,它看起来是正确的:

    ^([a-zA-Z\d\-!$@#$%^&*()|_+=\[\]{};,."'<>?/~`]{4,})$
    

    如果您真的打算将其用作密码验证器,它会散发出不安全的味道:

    • 为什么允许 4 个字符的密码?
    • 为什么要禁止某些字符? PHP不能处理一些?你为什么要关心?让用户输入他喜欢的字符,毕竟你最终会存储一个哈希+盐。

    【讨论】:

    • \w 字符类将不仅仅匹配 ASCII。
    • 没错,这就是我没有使用它的原因。
    • @Johannes - 仅在 Perl 中。在 PCRE 中,我认为不会。
    • 但是 OP 没有提到平台
    • @Vinko Vrsalovic:我不知道任何不会在无效字符范围上引发错误的实现。
    【解决方案5】:

    我注意到除了反斜杠、空格和开头的控制字符之外,您基本上拥有所有 ASCII,那么这个呢?

    ^([!-\[\]-~]{4,})$
    

    【讨论】:

    • 基本上我在这里创建的是一个密码正则表达式,我需要的是一个不严格的正则表达式(不要求你有一个大写,一个特殊字符,一个数字等等),但仍然有一个“好”字符的白名单。你的正则表达式能做到吗?
    • 顺便说一句,除了上面的数据,我在 PHP 中使用了带有 preg_match 的正则表达式。
    • 为什么要禁止某些字符?你到底为什么允许 4 个字符的密码??
    • Nikko:这个正则表达式在功能上与你的相同,它包括除了
    猜你喜欢
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多