I generate rainbow-tables as shown below.
Now two questions:
- How can I do this without using bigint (e.g. 2 nested for-loops) while retaining the order (meaning alphabet 0-9 counts from 0 to 99 for 2 digits) ?
- What are the various ways to generate the hash-table faster/most-efficient, making use of all processor slots and all cores ?
On 2), my take is partition the range into various groups, and execute this in threads.
This however would not use the different cores, unless .NET does that automagically (i have 4 processors with 2 cores each).
(entire project on https://github.com/ststeiger/RainbowTableGenerator)
using System.Windows.Forms;
namespace RainbowTableGenerator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
NativeMethods.SetPlaceHolderText(this.txtNumDigits, "Num Digits");
}
private void btnPermute_Click(object sender, System.EventArgs e)
{
int digits;
if (!System.Int32.TryParse(this.txtNumDigits.Text, out digits))
digits = 2;
this.dgvDisplayData.DataSource = Permute(digits);
}
public static string MD5(string input, System.Text.Encoding enc)
{
// step 1, calculate MD5 hash from input
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = enc.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
public System.Data.DataTable Permute(int digits)
{
this.txtNumDigits.Text = digits.ToString();
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("i", typeof(System.Numerics.BigInteger));
dt.Columns.Add("Text", typeof(string));
dt.Columns.Add("MD5-Hash (ASCII)", typeof(string));
dt.Columns.Add("MD5-Hash (UTF8)", typeof(string));
// char[] allowedAlphabet = new char[] { '0', '1'};
// char[] allowedAlphabet = new char[] { '0', '1', '2'};
// char[] allowedAlphabet = new char[] { 'a', 'b', 'c'};
// char[] allowedAlphabet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char[] allowedAlphabet = @"aåáàâäbcç¢deéèêëfghiïjklmnñoœóôöpqrsßtuûüvwxyzAÅÁÀÂÄBCÇ¢DEÉÈÊËFGHIÏJKLMNÑOŒÓÔÖPQRSTUÛÜVWXYZ #=+-_*°§%@¦|&!?.:;~^()[]{}<>\/€$£¬'`´""".ToCharArray();
// Add reference to System.Numerics.dll
System.Numerics.BigInteger numChars = allowedAlphabet.LongLength;
// int nm = (int)System.Math.Pow(numChars, digits);
System.Numerics.BigInteger nm = System.Numerics.BigInteger.Pow(numChars, digits);
System.Data.DataRow dr = null;
for (System.Numerics.BigInteger i = 0; i < nm; ++i)
{
// int decimalNumber = i;
// int remainder;
System.Numerics.BigInteger decimalNumber = i;
System.Numerics.BigInteger remainder;
string result = string.Empty;
do
{
// remainder = decimalNumber % numChars;
// decimalNumber /= numChars;
// result = remainder.ToString() + result;
remainder = System.Numerics.BigInteger.Remainder(decimalNumber, numChars);
decimalNumber = System.Numerics.BigInteger.Divide(decimalNumber, numChars);
int iRemain = (int)remainder;
result = allowedAlphabet[iRemain].ToString() + result;
} while (decimalNumber > 0);
dr = dt.NewRow();
dr["i"] = i;
dr["Text"] = result;
dr["MD5-Hash (ASCII)"] = MD5(result, System.Text.Encoding.ASCII);
dr["MD5-Hash (UTF8)"] = MD5(result, System.Text.Encoding.UTF8);
dt.Rows.Add(dr);
// System.Console.WriteLine("Combination: {0}", result);
} // Next i
System.Console.WriteLine("Finished {0} entries", dt.Rows.Count);
System.Console.WriteLine(System.Environment.NewLine);
return dt;
} // End Function Permute
}
}
namespace RainbowTableGenerator
{
class NativeMethods
{
private const uint EM_SETCUEBANNER = 0x1501;
[System.Runtime.InteropServices.DllImport("user32.dll",SetLastError=true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern System.IntPtr SendMessage(System.IntPtr hWnd, uint msg, System.IntPtr wParam,
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]string lParam);
// http://www.fluxbytes.com/csharp/set-placeholder-text-for-textbox-cue-text/
public static void SetPlaceHolderText(System.Windows.Forms.TextBox txt, string Text)
{
if(System.Environment.OSVersion.Platform != System.PlatformID.Unix)
SendMessage(txt.Handle, EM_SETCUEBANNER, System.IntPtr.Zero, Text);
}
}
}