驗證密碼不包含連續遞增/遞減字元序列(如 1234、abcd、4321、dcba),允許無序字元(1326、dies)。
// 預生成所有長度>=4 的連續序列
static let forbiddenSequences: Set = {
var set = Set()
// 數字 0-9
for i in 0...6 { // 0123, 1234, ..., 6789
let seq = String((i...i+3).map { String($0) }.joined())
set.insert(seq)
set.insert(String(seq.reversed())) // 遞減
}
// 小寫字母 a-z
for i in 0...22 {
let seq = String((i...i+3).map { Character(UnicodeScalar(97+$0)!) }.map(String.init).joined())
set.insert(seq)
set.insert(String(seq.reversed()))
}
// 大寫字母 A-Z
for i in 0...22 {
let seq = String((i...i+3).map { Character(UnicodeScalar(65+$0)!) }.map(String.init).joined())
set.insert(seq)
set.insert(String(seq.reversed()))
}
return set
}()
func isPasswordValid(_ password: String) -> Bool {
// 檢查所有子字串長度>=4
for len in 4...password.count {
for i in 0...(password.count - len) {
let sub = String(password.dropFirst(i).prefix(len))
if forbiddenSequences.contains(sub) { return false }
}
}
return true
}
func hasSequentialChars(_ password: String, minLength: Int = 4) -> Bool {
let chars = Array(password.unicodeScalars.map { Int($0.value) })
guard chars.count >= minLength else { return false }
var incCount = 1, decCount = 1
for i in 1..= minLength || decCount >= minLength { return true }
}
return false
}
func isPasswordValid(_ password: String) -> Bool {
return !hasSequentialChars(password)
}
優勢:無需預生成表、支援任意 Unicode 連續字元、O(n) 時間複雜度。
// iOS 12+ 密碼自動強度建議
textField.passwordRules = UITextInputPasswordRules(descriptor: "required: upper; required: lower; required: digit; required: special; minlength: 8;")
// 系統鍵盤會提示生成強密碼
密碼驗證核心:黑名單攔截已知弱模式 + 白名單鼓勵高熵值,動態檢測連續字元碼比預生成表更通用高效。