If you already have access to the hashed version of the password, MD5 is broken to start with . However, when it comes to hashing, you will probably be better off using Rainbow Tables , Attack Dictionary, and Social Engineering using your brute force method. However, since you asked the algorithm to generate all the values, perhaps the following will be useful (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 ); for (int desiredLength = 1; desiredLength <= MaxLength; ++desiredLength) { BuildWord(0 , desiredLength, new char[MaxLength]); } } } }
To be completely honest, this can be further optimized. Since he builds all the โwordsโ of length 1, this works the second time when building words of length 2. It would be wiser to build words of length MaxLength, and then truncate one letter to build the word MaxLength-1.
Here is the optimized version ... note that it does NOT return words in the originally requested order.
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 ); BuildWord(0 , MaxLength, new char[MaxLength]); } } }