2020-02-22 23:23:02 +08:00
|
|
|
//
|
|
|
|
|
// PasswordGeneratorFlavour.swift
|
|
|
|
|
// passKit
|
|
|
|
|
//
|
|
|
|
|
// Created by Danny Moesch on 28.11.18.
|
|
|
|
|
// Copyright © 2018 Bob Sun. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import KeychainAccess
|
|
|
|
|
|
|
|
|
|
public enum PasswordGeneratorFlavor: String {
|
|
|
|
|
case apple = "Apple"
|
|
|
|
|
case random = "Random"
|
2020-02-23 03:06:23 +08:00
|
|
|
case xkcd = "XKCD"
|
2020-02-22 23:23:02 +08:00
|
|
|
|
|
|
|
|
public var localized: String {
|
|
|
|
|
return rawValue.localize()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public var longNameLocalized: String {
|
|
|
|
|
switch self {
|
|
|
|
|
case .apple:
|
|
|
|
|
return "ApplesKeychainStyle".localize()
|
|
|
|
|
case .random:
|
|
|
|
|
return "RandomString".localize()
|
2020-02-23 03:06:23 +08:00
|
|
|
case .xkcd:
|
|
|
|
|
return "XKCDStyle".localize()
|
2020-02-22 23:23:02 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public var defaultLength: (min: Int, max: Int, def: Int) {
|
|
|
|
|
switch self {
|
|
|
|
|
case .apple:
|
|
|
|
|
return (15, 15, 15)
|
|
|
|
|
case .random:
|
|
|
|
|
return (4, 64, 16)
|
2020-02-23 03:06:23 +08:00
|
|
|
case .xkcd:
|
|
|
|
|
return (2, 5, 3)
|
2020-02-22 23:23:02 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public func generate(length: Int) -> String {
|
|
|
|
|
switch self {
|
|
|
|
|
case .apple:
|
|
|
|
|
return Keychain.generatePassword()
|
|
|
|
|
case .random:
|
|
|
|
|
return PasswordGeneratorFlavor.generateRandom(length: length)
|
2020-02-23 03:06:23 +08:00
|
|
|
case .xkcd:
|
|
|
|
|
return PasswordGeneratorFlavor.generateXKCD(length: length)
|
2020-02-22 23:23:02 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static func generateRandom(length: Int) -> String {
|
|
|
|
|
let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_+-="
|
|
|
|
|
return String((0..<length).map { _ in chars.randomElement()! })
|
|
|
|
|
}
|
2020-02-23 03:06:23 +08:00
|
|
|
|
|
|
|
|
private static func generateXKCD(length: Int) -> String {
|
|
|
|
|
// Get the word list
|
|
|
|
|
let bundle = Bundle(identifier: Globals.passKitBundleIdentifier)!
|
|
|
|
|
guard let asset = NSDataAsset(name: "WordLists", bundle: bundle),
|
|
|
|
|
let data = String(data: asset.data, encoding: .utf8) else {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
let words = data.splitByNewline()
|
|
|
|
|
|
|
|
|
|
// Generate a password
|
|
|
|
|
let delimiters = "0123456789!@#$%^&*_+-="
|
|
|
|
|
var password = ""
|
|
|
|
|
(0..<length).forEach { _ in
|
|
|
|
|
var word = words.randomElement()!
|
|
|
|
|
if Bool.random() {
|
|
|
|
|
word = word.uppercased()
|
|
|
|
|
}
|
|
|
|
|
password += word + String(delimiters.randomElement()!)
|
|
|
|
|
}
|
|
|
|
|
return password
|
|
|
|
|
}
|
2020-02-22 23:23:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension PasswordGeneratorFlavor: CaseIterable {}
|