If you already have access to the hashed version of the password, then MD5 is broken to begin with. That said, when it comes to breaking a hashed value, you'd likely be better off using Rainbow Tables, Dictionary Attacks, and Social Engineering over your brute force method. That said, since you asked for an algorithm to generate all the values, maybe the following will be beneficial (C#):
using System;
using System.Text;
namespace PossibiltyIterator
{
class Program
{
static readonly char[] Symbols = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&',
'*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"',
',', '.', '<', '>', '?', '`', '~'
};
const int MaxLength = 8;
static void BuildWord(int currentLength, int desiredLength, char[] word)
{
if (currentLength == desiredLength)
{
Console.WriteLine(word);
}
else
{
for (int value = 0; value < Symbols.Length; ++value)
{
word[currentLength] = Symbols[value];
BuildWord(currentLength + 1, desiredLength, word);
}
}
}
static void Main(String[] args)
{
double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true /* intercept */);
for (int desiredLength = 1; desiredLength <= MaxLength; ++desiredLength)
{
BuildWord(0 /* currentLength */, desiredLength, new char[MaxLength]);
}
}
}
}
To be completely honest, this can be optimized further. Because it builds all the "words" of length 1, then does that work a second time in building the words of length 2. It would be smarter to build the words of length MaxLength, then truncate one letter to build a word of MaxLength-1.
Here is the optimized version... note that it does NOT return the words in the order originally requested.
using System;
using System.Text;
namespace PossibiltyIterator
{
class Program
{
static readonly char[] Symbols = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&',
'*', '(', ')', '-', '_', '+', '=', '/', '\\', '[', ']', '{', '}', ';', ':', '\'', '"',
',', '.', '<', '>', '?', '`', '~'
};
const int MaxLength = 8;
static void BuildWord(int currentLength, int desiredLength, char[] word)
{
if (currentLength != desiredLength)
{
for (int value = 0; value < Symbols.Length; ++value)
{
word[currentLength] = Symbols[value];
BuildWord(currentLength + 1, desiredLength, word);
}
word[currentLength] = '\0';
}
Console.WriteLine(word);
}
static void Main(String[] args)
{
double totalValues = (Math.Pow(Symbols.Length, MaxLength + 1) - Symbols.Length)/(Symbols.Length - 1);
char[] word = new char[MaxLength];
Console.WriteLine("Warning! You are about to print: {0} values", totalValues);
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true /* intercept */);
BuildWord(0 /* currentLength */, MaxLength, new char[MaxLength]);
}
}
}