Neil Ang

Developer

A stunning likeness of Neil Ang
Hello world

How to write a password generator

Posted on

Using an app to generate random passwords just makes sense. Here is my attempt at making one.

The source for this project can be found on github.

Picture of final product

Password generator

For this project I wanted the user to be able to select the types of symbols that will appear in the password. I'm going to assume you are already familiar with setting up interfaces and connecting them with IBOutlets and IBActions (if not, examine the provided source code).

NB: Although this is an objective-c project, I've dropped back to C to do do most of the work. Manipulating characters in c-strings is very efficient and simple.

The first step is to determine how long the password will be, and what characters it will be built from:

int letters  = ...; // set these values from your input controls
int capitals = ...;
int digits   = ...;
int symbols  = ...;
int length   = letters + capitals + digits + symbols;

char *lettersAlphabet  = "abcdefghijklmnopqrstuvwxyz";
char *capitalsAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *digitsAlphabet   = "0123456789";
char *symbolsAlphabet  = "!@#$%*[];?()";

Then declare an empty string of the right length which we will fill with these random characters. We will also need a second char pointer that points to this string:

// Build the password using C strings - for speed
char *cPassword = calloc(length + 1, sizeof(char));
char *ptr       = cPassword;

cPassword[length - 1] = '\0'; // terminate the c-string

Now for each alphabet set, we will need to add the required amount of symbols. I've used a helper function to reduce duplication:

ptr = appendRandom(ptr, lettersAlphabet, letters);
ptr = appendRandom(ptr, capitalsAlphabet, capitals);
ptr = appendRandom(ptr, digitsAlphabet, digits);
ptr = appendRandom(ptr, symbolsAlphabet, symbols);

This is what the helper function looks like:

char *appendRandom(char *str, char *alphabet, int amount) {
  for (int i = 0; i < amount; i++) {
    int r = arc4random() % strlen(alphabet);
    *str = alphabet[r];
    str++;
  }

  return str;
}

Notice how it advances the string pointer after it appends each character? This is why we needed to create the second char pointer.

Next, we rearrange the symbols in the string so the different alphabet types aren't grouped together:

for (int i = 0; i < length; i++) {
  int  r    = arc4random() % length;
  char temp = cPassword[i];
  cPassword[i] = cPassword[r];
  cPassword[r] = temp;
}

Finally, convert the c-string back into an objective-c string, and don't forget to free any allocated memory.

NSString *thePassword = [NSString stringWithCString:cPassword encoding:NSUTF8StringEncoding];

free(cPassword);

Download the full code for this project from GitHub.