Skip to content

Instantly share code, notes, and snippets.

@hamishknight
Last active May 22, 2017 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hamishknight/08f898c746dcc25e6d11e7401dc1c4a2 to your computer and use it in GitHub Desktop.
Save hamishknight/08f898c746dcc25e6d11e7401dc1c4a2 to your computer and use it in GitHub Desktop.
Swift random password generator
import Foundation
struct PasswordGenerator {
var length: Int
var characterSet: CharacterSet {
didSet {
// re-compute the characters array after the character set changing.
characters = Array(characterSet.characters)
}
}
// cached characters.
private var characters: [Character]
// default options of just using letters (upper and lowercase)
init(length: Int, characterSet: CharacterSet = .letters) {
self.length = length
self.characterSet = characterSet
self.characters = Array(characterSet.characters)
}
/// Generate a new password from the given character set.
///
/// - Precondition: The character set must be non-empty.
func generate() -> String {
// we cannot generate a password if there's no characters to generate it from.
precondition(!characters.isEmpty,
"Cannot generate password from an empty character set.")
let characterCount = UInt32(characters.count)
let result = (0 ..< length).map { _ in
characters[Int(arc4random_uniform(characterCount))]
}
return String(result)
}
}
extension PasswordGenerator {
struct CharacterSet : OptionSet {
static let lowercase = CharacterSet(rawValue: 1 << 0)
static let uppercase = CharacterSet(rawValue: 1 << 1)
static let numbers = CharacterSet(rawValue: 1 << 2)
static let symbols = CharacterSet(rawValue: 1 << 3)
static let letters: CharacterSet = [.lowercase, .uppercase]
static let alphanumeric: CharacterSet = [.letters, .numbers]
let rawValue: Int
var characters: Set<Character> {
var characters = Set<Character>()
if contains(.lowercase) { // in Swift 4, remove ".characters"
characters.formUnion("abcdefghijklmnopqrstuvwxyz".characters)
}
if contains(.uppercase) {
characters.formUnion("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
}
if contains(.numbers) {
characters.formUnion("1234567890".characters)
}
if contains(.symbols) {
characters.formUnion("!@#$%^&*".characters)
}
return characters
}
}
}
var passwordGenerator = PasswordGenerator(length: 16, characterSet: .alphanumeric)
print(passwordGenerator.generate()) // GcWrH81pYU46m4lx
passwordGenerator.length = 20
print(passwordGenerator.generate()) // 9SNiPlgYqRCpvpP96cuT
passwordGenerator.characterSet.subtract(.lowercase)
print(passwordGenerator.generate()) // YX1WELZEC7GN4L2JTAVR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment