Password Generator in Swift
Simple password generator in Swift.
One day I was chatting with other iOS devs and someone posted an example of password generator code. The code featured “for-i-in” loops and other things which didn’t look much swifty to my eye.
I tried to find a real application for nice Swift features like generators, sequences and some functional methods like
reduce. I went through a number of iterations to get to the final state. Here’s the code I eventually came up with.
As you can see this code is using Swift 1.2 features, such as new
Set data type.
The general idea is to create a password generator for a given set of characters to generate passwords of the given length. I’m not claiming here that this is the best design ever. Probably it would be better to have a function that takes a set of characters and password length as an input and then do all heavy lifting in that function.
However, let’s walk through this code.
PasswordGenerator is a sequence since it conforms to
SequenceType protocol. As part of protocol implementation this struct needs to implement
generate() function that returns another Swift type
Generator. In this example I’m generating characters for a password, so I chose to initialize password generator with a set of characters (
characters) and length of the password to be generated (
Note that I’m not using any unicode specific code at all. That’s the beauty of
String type in Swift. Since
String conforms to the very same
SequenceType it can easily be converted to an array or a set, and what’s even better, it will be an array or a set of unicode characters.
OK, so back to
generate() function returns generator of
GeneratorOf is another Swift generic type useful to declare generators of a certain type. Inside the function I’m creating a generator of
Character with a closure, this closure captures
currentLength variable as well as
self. The closure first generates a random index of an element in the set using good old
randomIndex is of type
Int and can not be used as a set index. The set index in this case needs to be of type
SetIndex<Character>. To get set index I’m using standard library function
advance that gives me a
randomIndex set index equivalent for a set. Finally I can get a character from the set, incrementing
currentLength and comparing it to
self.length along the lines to know when to stop. Note the use of
self, this is required because it’s a closure.
Last step is to implement
password() function that actually generates passwords. This is where I can use the fact that
PasswordGenerator is a sequence. Thanks to that I am able to use standard library
self. Reduce iterates through the sequence on each step getting a random element from the characters set it then appends new character to accumulator string using
Without a single for-i-in loop I get a simple password generator that demoes beauty and flexibility of Swift and is yet open for further improvements.
blog comments powered by Disqus