For years now, I've used a simple but effective way to generate passwords that are easy to remember but impossible to crack. I select a pair of random words from a dictionary and combine them, sometimes with a number or symbol separating them.
Earlier this week I found a large (109582 words) word list file on the net, and decided to automate the process.
I wrote a dirt simple Mac application that generates passwords using 2 randomly selected words, separated with a number between 1 and 99. Since the word list is 109582 words, the total number of possible passwords is 109582 * 109582 * 99, or 1,188,813,257,676. That's over 1 TRILLION possible combinations.
I decided to post the app here as a tutorial. It's a Mac app instead of an iOS app, but just about all of the techniques it uses are exactly the same between Mac OS and iOS.
You can download the project from my mobileMe public folder at the following link:
Password generator project
The app demonstrates a number of useful things:
- Converting a text file into a binary plist.
- Reading a plist file into an array.
- Using arc4random to select items from an arbitrary sized array of objects.
- Using a data container singleton to share data between objects in a project
- Using a shared utilities (singleton) class to collect common utilities functions. The utilities class includes both class methods (which you can call without having to create an instance of the utilities class) and instance methods.
Running the project requires a word list to work. I wrote it to use a word list file that I found on the web at SIL International
. Click that link to download the file..
The project is written with an "if (TRUE)" statement that runs a one time setup method that converts the text file into a binary plist. The program expects the source file to be named wordsEn.txt, and saved in the documents directory for the current user on your Mac.
Once you run the program once, it puts up an alert telling you that the plist file has been created. You will then need to drag the plist file into your project's "supporting files" group and click the "copy items into destination group's folder (if needed)" checkbox in the dialog that XCode displays. This will cause XCode to include the plist file in your app bundle.
Once you've copied over the plist file into your project, go to the app delegate and search for "if (TRUE)". Change that line to "if (FALSE)" and the program will no longer create the word list plist file, but will instead try to open the plist file from the bundle at startup.
The program converts the word list into a BINARY plist because binary plists are MUCH faster and MUCH smaller than XML plists. That's an important point for iOS apps, since iOS devices are both slower than Macs and very memory/disk starved. Take a look at the code that saves and loads the plist file. It uses class methods from the NSPropertyListSerialization class instead of the normal NSArray writeToFile:atomically and arrayWithContentsOfFile methods.
The program uses a data container singleton class so it can share data between it's different objects. This is more as a tutorial than anything, since this app really only has an app delegate, and that's about it. The data container singleton class is called DataContainerSingleton. It has a class method theDataContainerSingleton that lets you get to the data container object from any object in your app, using code like this:
If you want to make some value visible from your entire application, simply add a property to the data container singleton object, and read/write to the property using the above syntax. That's all there is to it.