由於 (?=) 和 (?!) 的用法之前有在 這篇文章 大略提過, 所以此篇就當做是為了避免自己忘掉, 且做為衍生應用寫的吧.
關於密碼驗證的 Regular Expression, 我自己在網路上找到的是以下這個:
^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$上述的 Regular Expression 可達到以下幾個驗證密碼的項目:
- (?=.{10,}): 密碼長度 10 個以上
- (?=.*\d): 至少要有一個 0-9 的數字
- (?=.*[a-z]): 至少要有一個小寫的英文字母 (a-z)
- (?=.*[A-Z]]): 至少要有一個大寫的英文字母 (A-Z)
- (?=.*[@#$%^&+=]): 至少要有清單中的一個特殊符號 (@#$%^&+=)
技巧上很簡單, 把每個 (?=) 項目都當做個驗證的關卡來看, 要通過這個密碼驗證, 就要每一關都通過.
至於整個 Regular Expression 最後面的 .* 是一定要有的, 前面的 .* 可有可無.如果兩個都沒有, 或是只有前面有 .*, 都是不行的. (有興趣的可以多方嘗試)
以下說明一下各個驗證的項目: (記住: 不管是 (?=) 或 (?!), .* 都記得先放進去)
- (?=.{10,}): 檢查輸入的字元長度是否有超過 10. 如果資料庫裡的密碼欄位長度是 20, 那就改成 (?=.{10,20}).
- (?=.*\d): 因為 \d 表示 [0-9], 所以此部分是檢查輸入的字串裡有沒有 0-9 的數字.
- (?=.*[a-z])(?=.*[A-Z]): 概念同 (?=.*\d), 不過這是分開檢查有沒有輸入大寫與小寫英文字母. 如果只是要有英文字母, 就改成 (?=.*[a-zA-Z]).
- (?=.*[@#$%^&+=]): 要使用者輸入至少一個指定的特殊符號. 有人會用 (?=.*\W) 來表示,因為 \W 表示 [^A-Za-z0-9_],這邊要注意 \W 有排除掉 '_' 這個符號.
由於大多數的程式設計師不會將密碼欄位的資料型態訂成 nvarchar, 所以我們可以再多加一個不允許雙字元輸入的判斷, 以避免真的有人來亂的.
這時候就要參考一下 ASCII 字元表, 查一下要排除的字元有哪些.
如果只是要排除雙字元, 那麼就多加一個以下的判斷:
(?!.*[^\x00-\xff]): 表示不允許輸入 ASCII 以外的字元.
不過, 也許有人發現, ASCII 字元表中, 也不是所有的字元都應該要接受.
至少我認為 \x00 到 \x20, 以及 \x7F 到 \xFF 這個範圍內的都不需要, 只有 \x21 到 \x7E 的部分是可接受輸入的.
所以可以再修改一下上面僅允許 ASCII 的驗證, 改成如下的驗證:
(?!.*[^\x21-\x7e]): 表示不允許輸入 \x21 到 \x7E 以外的字元.
最後, 我密碼驗證的 Regular Expression 如下:
^(?!.*[^\x21-\x7e])(?=.{4,10})(?=.*[\W])(?=.*[a-zA-Z])(?=.*\d).*$上述的 Regular Expression 可達到以下幾個驗證密碼的項目 (依序):
- 不允許特殊符號, 數字, 英文字母以外的字元輸入
- 密碼長度 4 到 10 個字元
- 至少要有一個特殊符號
- 至少要有一個大寫或小寫的英文字母
- 至少要有一個 0-9 的數字
不過要注意的是, 在 Web 用的 Regular Expression 跟透過 C# 或 VB 的 Regex 物件做出的判斷會有不一樣的地方.
例如,將長度驗證的部分拿到 (?=) 以外的地方去做, 如下例:
^(?!.*[^\x21-\x7e])(?=.*[\W])(?=.*[a-zA-Z])(?=.*\d).{4,10}$在 RegularExpressionValidator 中, 輸入 "111!!@A" 會驗證不過, 但改成 "111!!@A@1A" 卻又可驗證過.
而在 C# 的程式中, 以下兩個都會回傳 True:
Regex regex = new Regex( @"^(?!.*[^\x21-\x7e])(?=.*[\W])(?=.*[a-zA-Z])(?=.*\d).{4,10}$"); Console.WriteLine(regex.IsMatch("111!!@A")); Console.WriteLine(regex.IsMatch("111!!@A@1A"));所以, 個人建議將所有的判斷都寫在 (?=) 或 (?!) 中.
沒有留言:
張貼留言