Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Wednesday, 13 October 2010

 

spectrum_800

Look at the G key :-)

/// <summary>
/// A rolling brute force attack on a secret password
/// The program knows the password is only lowercase letters, but doesn't know the length
///
/// Starting at: a
/// then b
/// then c
/// ...
/// then z
/// then aa
/// then ab
/// ...
/// then ba
/// then bb
/// ...
/// then ca
/// then cb
/// ...
///
/// try to find secret password of: davedave
/// </summary>

Here is some of the code I used.

public class PasswordGuesser
{
public string SecretPassword { get; set; }

public int CrackPassword()
{
int numberOfIterationsCrackingPassword = 0;

for (int i = 97; i < 123; i++) // 1 column
{
numberOfIterationsCrackingPassword++;
string letterToTest = ((char)i).ToString();
if (letterToTest == SecretPassword)
goto Foo;
}

for (int i = 97; i < 123; i++) // 2 columns
{
for (int j = 97; j < 123; j++)
{
numberOfIterationsCrackingPassword++;
string testingLetters = ((char)i).ToString() + ((char)j).ToString();
if (testingLetters == SecretPassword)
goto Foo;

}
}
yikes, left out the Foo bit.. here is a more recent example of the code:

image

pro

  • works
  • testable
  • easy to read

con

  • slow
  • inelegant

Version 4 – As Shown in ScreenCast

    Source (VS2010)

http://stackoverflow.com/questions/324831/breaking-out-of-a-nested-loop    - use an anonymous method would be another way

This came from a  fun project which a bunch of use tried a few years ago http://www.programgood.net/2010/10/12/CodeGuessingProgram.aspx 

Version 5 – Speedy (thanks to DaveMul)

I had to remember to run in release mode!  Intel Core2 Dual 2.4GHz.  Compiling in .NET4

davedav - 1,257,688,584...27.5 secs in debug.  45/6m iterations/sec
                        9.5 secs in release. 132m iterations.sec
zzzzzzz - 8,353,082,582...184secs in debug.  45m iterations/sec

davedave - 32,699,903,189iterations 245secs.. 4min 5secs. 133m iterations/sec
zzzzzzzz - 217,180,147,158iterations 1636secs.  133m iterations/sec   

This is significantly faster than 3 years ago. for davedav – took 23secs, and now takes 9.5 secs.

Source is here:

pro:

  • fast

con:

  • feels like there should be a better way

future:

  • use parallel library in .NET4 to use multiple cores
  • refactor so am not repeating code (DRY – Don’t Repeat Yourself, Don’t Rep…….)

 

Historial: Version 1


Here are some of the tests:

using CodeGuesserApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;

namespace Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Get_One_Column_List_Of_Strings_Check_First_Letter_Is_a()
{
PasswordGuesser codeGuesser = new PasswordGuesser();
List<string> listOfStrings = codeGuesser.Get_List_Of_Strings_a_to_z();
Assert.AreEqual(listOfStrings[0], "a");
}

[TestMethod]
public void Get_one_column_list_of_strings_check_last_letter_is_z()
{
PasswordGuesser codeGuesser = new PasswordGuesser();
List<string> listOfStrings = codeGuesser.Get_List_Of_Strings_a_to_z();
Assert.AreEqual(listOfStrings[25], "z");
}

[TestMethod]
public void Get_two_column_list_of_strings_check_first_is_aa()
{
PasswordGuesser codeGuesser = new PasswordGuesser();
List<string> listOfStrings = codeGuesser.Get_List_Of_Strings_aa_to_zz();
Assert.AreEqual(listOfStrings[0], "aa");
}
}
}

and some of the code so far:

public class PasswordGuesser
{
public string SecretPassword { get; set; }

public List<string> Get_List_Of_Strings_a_to_z()
{
List<string> listOfStrings = new List<string>();
for (int i = 97; i < 123; i++)
{
string thingToAdd = ((char)i).ToString();
listOfStrings.Add(thingToAdd);
}
return listOfStrings;
}

public List<string> Get_List_Of_Strings_aa_to_zz()
{
List<string> listOfStrings = new List<string>();
for (int i = 97; i < 123; i++)
{
for (int j = 97; j < 123; j++)
{
string thingToAdd = ((char)i).ToString() + ((char)j).ToString();
listOfStrings.Add(thingToAdd);
}
}
return listOfStrings;
}

public int CrackPassword()
{
int iterationCounter = 1;

List<string> firstColumnListOfStrings = Get_List_Of_Strings_a_to_z();
foreach (string characterToTest in firstColumnListOfStrings)
{
if ((characterToTest == SecretPassword))
{
return iterationCounter;
}
iterationCounter++;
}


List<string> secondColumnListOfStrings = Get_List_Of_Strings_aa_to_zz();
foreach (string stringOfLength2ToTest in secondColumnListOfStrings)
{
if ((stringOfLength2ToTest == SecretPassword))
{
return iterationCounter;
}
iterationCounter++;
}
return 0;
}
}

class Program
{
static void Main(string[] args)
{
PasswordGuesser codeGuesser = new PasswordGuesser();
codeGuesser.SecretPassword = "zz";
int numberOfIterations = codeGuesser.CrackPassword();
Console.WriteLine("Total iterations: " + numberOfIterations.ToString());
}
 
image

Pros
  • It works
  • I’m confident it is working well as the tests prove it
Cons:
  • It is slow
  • Lots of code
  • Not built out to handle 8 letters (many billions of iterations)
  • Wont scale well

Version 2

image

Pros
  • Becoming a bit more compact with the ‘blank’ character of 96
  • Testable
Cons
  • Has to generate a list before it can crack the password against it

Version 3

public class PasswordGuesser
{
public string SecretPassword { get; set; }

public int CrackPassword()
{
int numberOfIterationsCrackingPassword = 1;
StreamWriter file = new StreamWriter("c:\\passwordOutput.txt");
for (int i = 96; i < 123; i++) // treating 96 as a blank
{
for (int j = 96; j < 123; j++)
{
for (int k = 97; k < 123; k++)
{
string lines = ((char)i).ToString() + " " + ((char)j).ToString() + " " + ((char)k).ToString();
file.WriteLine(lines);

if ((i == 96) && (j == 96)) // 1 column
{
string letterToTest = ((char)k).ToString();
if (letterToTest == SecretPassword)
goto Foo;
}
else if ((i == 96) && (j != 96)) // 2 column
{
string testingLetters = ((char)j).ToString() + ((char)k).ToString();
if (testingLetters == SecretPassword)
goto Foo;
}
else // 3 column
{
string testingLetters = ((char)i).ToString() + ((char)j).ToString() + ((char)k).ToString();
if (testingLetters == SecretPassword)
goto Foo;
}
numberOfIterationsCrackingPassword++;
}
}
}
file.Close();
throw new Exception("Password not found");
Foo:
file.Close();
return numberOfIterationsCrackingPassword;
}
}

Unit test caught a bug in my logic.

image

Expected was 703, actual was 729.  What is going on? 

After dumping to a text file:

image

image

Ahh, so with 3 columns it is putting in a blank in the middle.  Interesting.

Pros

Cons

  • Can’t think of elegant way around this logic as I don’t want extra iterations eg a blank a is never valid

Go on to version 4 – make it simpler with multiple loops for each number of columns

Version 4

public class PasswordGuesser
{
public string SecretPassword { get; set; }
StreamWriter file = new StreamWriter("c:\\passwordOutput.txt");

public int CrackPassword()
{
int numberOfIterationsCrackingPassword = 1;

for (int i = 97; i < 123; i++) // 1 column
{
string letterToTest = ((char)i).ToString();
DoLoggingToTextFile(letterToTest);
if (letterToTest == SecretPassword)
goto Foo;
numberOfIterationsCrackingPassword++;
}

for (int i = 97; i < 123; i++) // 2 columns
{
for (int j = 97; j < 123; j++)
{
string testingLetters = ((char)i).ToString() + ((char)j).ToString();
DoLoggingToTextFile(testingLetters);
if (testingLetters == SecretPassword)
goto Foo;
numberOfIterationsCrackingPassword++;
}
}

for (int i = 97; i < 123; i++) // 3 columns
{
for (int j = 97; j < 123; j++)
{
for (int k = 97; k < 123; k++)
{
string testingLetters = ((char)i).ToString() + ((char)j).ToString() + ((char)k).ToString();
DoLoggingToTextFile(testingLetters);
if (testingLetters == SecretPassword)
goto Foo;
numberOfIterationsCrackingPassword++;
}
}
}

test code:

[TestMethod] // 132 seconds
public void Set_password_to_zzzzzz_and_check_it_takes_321million_iterations()
{
DateTime startTime = DateTime.Now;
Debug.Print("starting at: " + startTime);
PasswordGuesser passwordGuesser = new PasswordGuesser();
passwordGuesser.SecretPassword = "zzzzzz";
int numberOfIterations = passwordGuesser.CrackPassword();
Assert.AreEqual(321272406, numberOfIterations);
TimeSpan totalTime = DateTime.Now - startTime;
Debug.Print("total time in seconds for 6 cols zzzzzz: " + totalTime.TotalSeconds);
}

Slow - 132secs for zzzzzz 6 cols / 321million iterations.  Old code ran 23secs for 936million iterations

| | # 
# Tuesday, 12 October 2010

This was an older blog post from 2006, and I found the text from ‘The Wayback Machine’ ie web.archive.org, on davemateer.com

Whilst reading Simon Sing's - The Code Book (www.simonsingh.com)  I thought it would be fun to write a code guessing program.  My first try was in Visual Basic6, then I ported it over to C#.  Phil decided he'd have a go and wrote it in Python then Java.  Then Dan wrote it in C.  We were all intrigued as to how fast each language would be, and who would be the winner?


This program takes say x letters from lowercase a to z, in as a secretString (in all cases we used 'davedave' for 8, then 'davedav' for 7 etc..)  Then it tries to guess the secretString by starting at aaaaaaaa and finishing at zzzzzzzz (for the 8 length example).  It was not allowed guess each letter individually, it had to guess the entire string correctly.

My machine ran an Athlon 1500+ processor with 0.75gig of RAM, and WinXPSP2.

image

So Cv1.1 and C#v3 got pretty close.

C# v2 (thanks to Kelly)

namespace pattern_string_version2 

{

class Program

{

static void Main(string[] args)

{

string secretString = "davedave";

int counter = 0;



byte[] ts = new byte[8];



string timeStart;

string timeEnd;

timeStart = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString();

Console.WriteLine("time at start is {0}", timeStart);



//loop 1

for (byte i = 97; i < 123; i++)

{

//loop2

for (byte j = 97; j < 123; j++)

{

//loop3

for (byte k = 97; k < 123; k++)

{

//loop4

for (byte l = 97; l < 123; l++)

{

//loop5

for (byte m = 97; m < 123; m++)

{

//loop6

for (byte n = 97; n < 123; n++)

{

//loop7

for (byte o = 97; o < 123; o++)

{

//loop8

for (byte p = 97; p < 123; p++)

{

ts[0] = i;

ts[1] = j;

ts[2] = k;

ts[3] = l;

ts[4] = m;

ts[5] = n;

ts[6] = o;

ts[7] = p;



counter++;



string ts2 = System.Text.ASCIIEncoding.ASCII.GetString(ts, 0,8);



if (ts2.Equals(secretString))

{

Console.WriteLine("Found secret which is {0} after {1} pattern matches", ts, counter);

Console.WriteLine();

timeEnd = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString();

Console.WriteLine("time at end is {0}", timeEnd);

break;

}// End if

} //end loop 8

} // end loop 7

}// end loop 6

}//end loop5

}//end loop4

}//end loop3

}//end loop2

}//end loop1

}// End Main

}// End Program

}// End Namespace
 
 

C# V3 (thanks Dave Mulh, Phil, Darrin) – nested version

This may be the fastest C#?

using System;
using System.Text;

namespace pattern_string_version3
{
class PatternMatch
{
static void Main(string[] args)
{
byte[] SecretBytes = Encoding.UTF8.GetBytes("davedav");
//int counter = 0;
// A 64 bit type giving a large number
ulong counter = 0;
byte[] ComparisonBytes = new byte[7];
string timeStart;
string timeEnd;

timeStart = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString();

//loop 1
for (byte i = 97; i < 123; i++)
{
ComparisonBytes[0] = i;
//loop2
for (byte j = 97; j < 123; j++)
{
ComparisonBytes[1] = j;
//loop 3
for (byte k = 97; k < 123; k++)
{
ComparisonBytes[2] = k;
//loop4
for (byte l = 97; l < 123; l++)
{
ComparisonBytes[3] = l;
//loop 5
for (byte m = 97; m < 123; m++)
{
ComparisonBytes[4] = m;
//loop6
for (byte n = 97; n < 123; n++)
{
ComparisonBytes[5] = n;
//loop7
for (byte o = 97; o < 123; o++)
{
ComparisonBytes[6] = o;
//loop8
//for (byte p = 97; p < 123; p++)
//{
// ComparisonBytes[7] = p;

counter++;

//bool match = CompareByteArrays(ComparisonBytes,SecretBytes);
if (CompareByteArrays(ComparisonBytes, SecretBytes))
{
timeEnd = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString();
string matchedString = System.Text.ASCIIEncoding.ASCII.GetString(ComparisonBytes, 0, 7);
Console.WriteLine("Found secret which is {0} after {1} pattern matches", matchedString, "counter");
Console.WriteLine();
Console.WriteLine("time at start is {0}", timeStart);
Console.WriteLine("time at end is {0}", timeEnd);
Console.WriteLine("counter is {0}", counter);
break;
}// End
//} //end loop 8
}//end loop 7
} // end loop 6
}// end loop 5
} //end loop 4
} // end loop 3
}// end loop 2
}//end 1
//we failed, so output error
Console.WriteLine("Didn't Found secret which after {0} pattern matches", "counter");
Console.WriteLine("time at start is {0}", timeStart);
Console.WriteLine("time at end is {0}", DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString());
Console.ReadLine();
}// End Main

public static bool CompareByteArrays(byte[] data1, byte[] data2)
{
for (int i = 0; i < 7; i++)
{
if (data1[i] != data2[i])
{
return false;
}
}
return true;
}
}// End Program
}// End Namespace


C# (Kelly’s Byte by Byte cheat!)

using System;
using System.Text;

namespace Proto

{

/// <summary>

/// Summary description for Class1.

/// </summary>

class Class1

{

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main( string [] args)

{

byte [] SecretBytes = Encoding.UTF8.GetBytes("davedave");

byte [] ComparisonBytes = new byte [8] {97,97,97,97,97,97,97,97};

int index = 0;

string timeStart = String.Format("{0}:{1}:{2}", DateTime.Now.Hour.ToString(), DateTime.Now.Minute.ToString(), DateTime.Now.Second.ToString());

// Start Processing

while (SecretBytes.Length > index)

{

ComparisonBytes[index]++;

if (ComparisonBytes[index].Equals (SecretBytes[index]))

index++;

}

// End Processing

string timeEnd = String.Format("{0}:{1}:{2}", DateTime.Now.Hour.ToString(), DateTime.Now.Minute.ToString(), DateTime.Now.Second.ToString ());

string matchedString=System.Text.ASCIIEncoding .ASCII.GetString(ComparisonBytes, 0,8);

Console.WriteLine("Found secret which is {0} after {1} pattern matches",matchedString, "counter");

Console.WriteLine();

Console.WriteLine("time at start is {0}", timeStart);

Console.WriteLine("time at end is {0}", timeEnd);

Console.ReadLine();

}

}

}

PHP

PHP Code

Run from the command line eg php pattern.php

<?

$startTime = time();

echo "starting pattern match started <br \>";



$secretString = "daveda";

// loop1

for ($i = 97; $i < 123; $i ++)

{

$iChar = chr($i);

// loop2

for ($j = 97; $j < 123; $j++)

{

$jChar = chr($j);

// loop 3

for ($k = 97; $k < 123; $k++)

{

$kChar = chr($k);

// loop 4

for ($l = 97; $l < 123; $l++)

{

$lChar = chr($l);

// loop 5

for ($m = 97; $m < 123; $m++)

{

$mChar = chr($m);

// loop 6

for ($n = 97; $n < 123; $n++)

{

$nChar = chr($n);

$tryString = $iChar . $jChar . $kChar . $lChar . $mChar . $nChar;

if ($tryString == $secretString) {

echo "found secretString which is $tryString <br />" ;

$endTime = time();

$totalTime = $endTime - $startTime;

echo "Time taken in seconds is $totalTime <br />";

}// end if

} // end loop 6

} // end loop 5

} // end loop 4

} // end loop 3

}// end loop2

}// end loop1

?>

C (thanks to Dan)

Compiled with GCC, and run under Cygwin.
#include <stdio.h>
#include <time.h>

int main()
{
char * secretString = "davedave";
char tryString[10];
unsigned int counter = 0;
int i,j,k,l,m,n,o,p;
time_t start,end;

double dif;

unsigned int timeStart;
unsigned int timeEnd;

time (&start);

for (i = 'a'; i <= 'z'; i++)
{
for (j = 'a'; j <= 'z'; j++)
{
for (k = 'a'; k <= 'z'; k++)
{
for (l = 'a'; l <= 'z'; l++)
{
for(m = 'a'; m <= 'z'; m++)
{
for(n = 'a'; n <= 'z'; n++)
{
for(o = 'a'; o <= 'z'; o++)
{
for(p = 'a'; p <= 'z'; p++)
{
tryString[0] = (char)i;
tryString[1] = (char)j;
tryString[2] = (char)k;
tryString[3] = (char)l;
tryString[4] = (char)m;
tryString[5] = (char)n;
tryString[6] = (char)o;
tryString[7] = (char)p;
tryString[8] = '\0';

if ( strcmp( secretString, tryString ) == 0 )
{
time (&end);
dif = difftime (end, start);
printf( "\r\nSecretString is %s", tryString );
printf( "\r\nNumber combinations tried = %d", counter );
printf ("\r\nYou have taken %.2lf seconds to type your name.\n", dif );
return 1;
}
else
{
counter++;
}
}
}
}
}
}
}
}
}
printf("\r\nDid not find secret string %s after %d combinations", secretString, counter );
}
 

C v1.1 (thanks to Darrin)

This may be the fastest so far?

#include <stdio.h> 
#include <time.h>

int main()
{
char * secretString = "davedav";
char tryString[10];
unsigned int counter = 0;
int i,j,k,l,m,n,o,p;
time_t start,end;
double dif;

unsigned int timeStart;
unsigned int timeEnd;
time (&start);

for (i = 'a'; i <= 'z'; i++)
{
tryString[0] = i;
for (j = 'a'; j <= 'z'; j++)
{
tryString[1] = j;
for (k = 'a'; k <= 'z'; k++)
{
tryString[2] = k;
for (l = 'a'; l <= 'z'; l++)
{
tryString[3] = l;
for(m = 'a'; m <= 'z'; m++)
{
tryString[4] = m;
for(n = 'a'; n <= 'z'; n++)
{
tryString[5] = n;
for(o = 'a'; o <= 'z'; o++)
{
tryString[6] = o;
//for(p = 'a'; p <= 'z'; p++)
//{
//tryString[7] = p;
tryString[7] = '\0';
if ( strcmp( secretString, tryString ) == 0 )
{
time (&end);
dif = difftime (end, start);
printf( "\r\nSecretString is %s", tryString );
printf( "\r\nNumber combinations tried = %d", counter );
printf ("\r\nYou have taken %.2lf seconds to type your name.\n", dif );
return 1;
}
else
{
counter++;
}
//}
}
}
}
}
}
}
}
printf("\r\nDid not find secret string %s after %d combinations", secretString, counter );
}


C v2 (thanks to Dan) uses pointers

#include <stdio.h>
#include <time.h>

// This is the maximum length of the string we are trying to guess
#define MAX_SECRET_STRING_LENGTH 16

int
main( void )
{
char tryString[MAX_SECRET_STRING_LENGTH];
char *secretString = "davedav";
unsigned int numComparisons;
int strLen;
int i;
time_t start,end;
unsigned int timeStart;
unsigned int timeEnd;
double dif;

time (&start);

// Setting up start point of guesser
strLen = 0;
tryString[0] = 'a';
tryString[1] = '\0';
numComparisons = 0;
while ( 1 )
{
numComparisons++;
// Check if this is the string we're after
if ( !strcmp( tryString, secretString ) )
{
time (&end);
dif = difftime (end, start);
// We have found the string!
printf( "Secret string is: %s\r\n", tryString );
printf( "Number of comprisons: %d\r", numComparisons );
printf ("\r\nCode took %.2lf seconds to run.\n", dif );
return;
}

// String doesn't match so increment the most right hand character
tryString[strLen]++;

// Is most right hand character z?
if ( tryString[strLen] == 'z' )
{
// We need to roll one or more characters over to 'a'
// Count i backwards from strLen to 0
for ( i = strLen; i >= 0; i-- )
{
// Is the character at position i equal to z? It always will be on
// the first loop
if ( tryString[i] == 'z' )
{
// Have we reached position 0 ie the start of the string?
if ( i == 0 )
{
// We have just rolled over all the characters in our current try
// string and have not yet found a match. We must now try with
// a string 1 character longer.
strLen++;
tryString[0] = 'a';
tryString[strLen] = 'a';
// Delimit the string for the comparison
tryString[strLen + 1] = '\0';
break;
}
else
{
// We haven't reached the beginning of string, so set current character
// to a and previous character increment
tryString[i] = 'a';
tryString[i - 1]++;
}
}
else
{
// If we are not incrementing this character then we won't be
// incrementing any characters before it either. So break out of the for i loop
// and start incrementing the most right hand character again.
break;
}
} //for i...
} //if
} //while
}//main

C++ (thanks to Michael) Recursive Loop Simplified Version

Its performance is handicapped by its iterative deepening search method, oh well.

// MikesRecursivePattern.cpp : main project file.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <time.h>

using std::string;

// what length of string will it search for before it gives up...
const int MAX_SEARCH_LENGTH = 8;
string secretString, guess;
int iterations = 0;

// checks to see it the string matches the secret string
bool CompareString() {
++iterations;
return !guess.compare( secretString );
}

// recursive function for scanning string
bool SearchString( string::iterator it )
{
bool result = false;
if( it != guess.end() ) {
for( int letter = 97; letter < 123 && !result; ++letter ) {
*it = (char)letter;
if( result = CompareString() )
break;
result = SearchString( it + 1 );
}
}
return result;
}

int main()
{
std::cout << "Enter string to search for -->";
std::getline( std::cin, secretString );
time_t start,end;
time( &start );

for(int tryLength = 0; tryLength < MAX_SEARCH_LENGTH; ++tryLength ){
guess += "a";
if( SearchString( guess.begin() ) )
break;
}
time( &end );

if( CompareString() ) {
std::cout << "secret string: " << guess.c_str() << "\n";
} else {
std::cout << "failed to find string. aaargh\n";
}

std::cout << "iterations: " << iterations << "\n";
std::cout << "time (secs): " << difftime (end, start) << "\n";
//stop the nasty app closing without showing results
std::getline( std::cin, secretString );
}

C++ (thanks to Michael) Full Version

1) will find any length string you enter
2) the letters aren't hardcoded and can be changed but adding/subtracting to the letters string.  ( if you replace this with the searching section from the c code then it ought to be equally speedy )
At the moment it is windows only, but that is only the timing code.

 

#ifdef _WIN32 
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#define _WIN32_IE 0x0501

#include <windows.h>
#endif

#include <iostream>
#include <string>

// what length of string will it search for before it gives up...
const int MAX_SEARCH_LENGTH = 8;

// define the letters to search for ie. possible secret string letters/symbols etc
const std::string letters = "abcdefghijklmnopqrstuvwxyz";
// the letters string doesn't change
const std::string::const_iterator itLettersEnd = letters.end();

std::string secretString;


// counter
int iterations = 0;

// checks to see it the string matches the secret string
bool CompareString( const std::string& test ) {
++iterations;
return test.compare( secretString ) == 0;
}

// performs the search
class Search {
std::string test_;
// recursive function that searches the string
bool SearchString( std::string::iterator it ) {
bool result = false;
if( it != test_.end() ) {
// search all possible letters
for( std::string::const_iterator itLetter = letters.begin(); itLetter != itLettersEnd && !result; ++itLetter ) {
*it = *itLetter; if( CompareString( test_ ) ) {
result = true;
break;
}
// move to the next letter and call this function
result = SearchString( it + 1 ); } } return result;
}

public:
// constructor requires length of string to search
Search( int length ) : test_( length, 'a') {}

const char* GetString() const { return test_.c_str(); }
// call this to start the recursive search
bool SearchString() {
return SearchString( test_.begin() );
}
};


int main()
{
std::cout << "Enter string to search for -->";
std::getline( std::cin, secretString );
std::string result = "";
LARGE_INTEGER start;
QueryPerformanceCounter( &start );

for(int tryLength = 0; tryLength < MAX_SEARCH_LENGTH; ++tryLength ){
Search tryString(tryLength + 1);
if( tryString.SearchString() ) {
result = tryString.GetString();
break;
}
}


LARGE_INTEGER finish;
QueryPerformanceCounter( &finish );
LARGE_INTEGER freq;
QueryPerformanceFrequency( &freq );
double totalTime = (double)(finish.QuadPart - start.QuadPart) / freq.QuadPart;

if( !result.empty() ) {
std::cout << "secret string: " << result.c_str() << "\n";
} else {
std::cout << "failed to find string, aaargh\n"; }
std::cout << "iterations: " << iterations << "\n";
std::cout << "time (secs): " << totalTime << "\n";
//stop the nasty app closing immediately
std::getline( std::cin, secretString );
}
 

C++ Mininal Crazy Version (thanks to Michael)

I sacrificed speed somewhat for the sake of making it difficult to understand.
All the other programs on your site seemed to be taking it seriously! (it is only partially
obfuscated currently... just wait 'till I'm finished  ) As you will be able to tell it uses a
somewhat different approach from the other programs, although it still is a simple loop.
Anyway on my machine it runs about 80 seconds for 7 letters. This is handicapped by
searching the wrong direction: In reverse; vadevad takes only 10 secs.


davedave: -> 610 seconds
evadevad: -> 396 seconds


Maybe you need a palindrome? ( or maybe i should just reverse my algorithm ;-)   )
Anyway my code is pretty short (the algorithm is 6 lines) so here goes...

#include <iostream> 
#include <string>
#include <time.h>

typedef unsigned __int64 E;

int main()
{
std::cout << "Enter string to search for (12 letters max)...\n>> ";
char c, s[12]; std::cin >> s;
time_t b,f;
time( &b);

E y=0,e=0; int p, l = strlen( s ); for(p=0;p<l;e|=(E)p[s]-97<<p++*5);
for(;y!=e;++y); std::string O = "";
for(p=0;p<l;O+=97+((e>>p++*5)&31));
time( &f);
double t = difftime( f, b );
std::cout << "secret string: " << O.c_str() << std::endl;
std::cout << "iterations: " << y << std::endl;
std::cout << "time (secs): " << t << std::endl; }


Whew! There it goes This ought to work several compilers (with an appropriate substitution for the __int64 typedef for non-microsoft ones )

Also if you happen to have a 64bit machine lying I'm confident you could give this program a significant performance boost, since everything is, well, 64bit numbers.


Java (thanks to Phil)

import java.util.*;

public class RunMe {


public static void main(String[] args) {

int l1,l2,l3,l4,l5,l6,loop;
String a1,a2,a3,a4,a5,a6;
String secret,testword;
Date date;
long start,finish;
date = new Date();
start = date.getTime();
secret = "daveda";
loop=0;
for (l1=97;l1<=122;l1++){
for (l2=97;l2<=122;l2++){
for (l3=97;l3<=122;l3++){
for (l4=97;l4<=122;l4++){
for (l5=97;l5<=122;l5++){
for (l6=97;l6<=122;l6++){
byte[] bytes = new byte[1];
bytes[0] = (byte) l1;
a1 = new String(bytes);
bytes[0] = (byte) l2;
a2 = new String(bytes);
bytes[0] = (byte) l3;
a3 = new String(bytes);
bytes[0] = (byte) l4;
a4 = new String(bytes);
bytes[0] = (byte) l5;
a5 = new String(bytes);
bytes[0] = (byte) l6;
a6 = new String(bytes);

testword = a1 + a2 + a3 + a4 +a5 +a6;

loop = loop + 1;
if (testword.equals(secret)){
date = new Date();
finish = date.getTime();
System.out.println("Task completed in: (milliseconds) (loops):");
System.out.println(finish-start);
System.out.println (Integer.toString(loop));
}
}//loop 6
}//loop 5
}//loop 4
}//loop 3
}//loop 2
}//loop 1
}//end of method
} //end of class

Java Object Based Approach (thanks Phil)

public class Counter {
private String list;
private int x;

public Counter(){
x=0;
list = "abcdefghijklmnopqrstuvwxyz";
}

public int add(){
x=x+1;

if (x ==26) {
x=0;
return 1; //signifies a reset has occurred
}
return 0;

}

public String status(){
return list.substring(x,x+1);
}
public int length(){
return list.length ();
}

}// end of class

------------------------------------------
//OBJECT:Container.Java

import java.util.*;

public class Container {
Vector v;

public Container(){
v = new Vector();
}

public void addElement(Counter c){

//copy label ref to object... not actual copy of object!!
this.v.addElement(c);
}

public String reportAll(){

String out,working;
int t;
Enumeration e;
e=this.v.elements();
Counter c;

out = "";

//run thru all points and return as a single string
while (e.hasMoreElements()){
c=(Counter) e.nextElement();
out=out+(c.status());
}

//switch order - reverse
working = out;
out="";
for (t=working.length();t>0;t--){
out = out+ working.substring(t-1,t);
}
return out;
}

public int returnLength(){
return v.size();
}

public String returnLetter(int pos){
String l;
Counter lc;

lc=(Counter) v.elementAt(pos);
l = lc.status();

return l;

}

public int addOne(int pos){
Counter t;
int temp;
t = (Counter) v.elementAt (pos);
temp = t.add();
if (temp==1){
//counter reset need to add one to element left of current
return 1;
}
return 0;
}

}//end class

------------------------------------------

//MyDriver.Java

import java.util.Date;

// Java - Object based Brute Force PassWord Cracker
// Author - Phil Bartie - 1 Jan 2006

public class MyDriver {

public static void main(String[] args) {
String secret;
Counter c;
Container ct;
int temp,t;
long loop,start,finish;
Date date;
date = new Date();
start = date.getTime();
ct = new Container();
loop=0;
secret = "daveda";

//add basic unit
ct.addElement(new Counter());

while (ct.reportAll().compareTo(secret) !=0){
loop++;
//System.out.println(ct.reportAll());

temp = ct.returnLength(); // static value of length of vector

t=0;

while (ct.addOne(t)==1){
t++;

if (temp==t){ //character reached 'z' so need new counter object
ct.addElement(new Counter());
break;
}

}
}//end for loop

//report result and number of iterations required
System.out.println("MATCH for:"+ ct.reportAll()+" @ loop " + loop);
date = new Date();
finish = date.getTime();
System.out.println ("Task completed in: " + (finish-start)+" (milliseconds)");

}//end main method
}//end class

Python (Phil)

import time

# setup string to find by brute force
loopcounter =0
secret = "daveda"
starttime = time.strftime('%X')

print starttime

for l1 in range(97,122):
for l2 in range (97,122):
for l3 in range (97,122):
for l4 in range (97,122):
for l5 in range (97,122):
for l6 in range(97,122):
loopcounter=loopcounter+1
testword=chr(l1) + chr(l2) + chr(l3) + chr(l4)+chr(l5)+chr(l6)
if testword == secret:
print time.strftime('%X')
print testword + " found after"+str(loopcounter) +" iterations"
#terminate command needed here

Python (thanks Phil) Base 26 version

import string,time
alp = 'abcdefghijklmnopqrstuvwxyz'

def ntb(num, base):
stack = []
while num:
stack.append(alp[num % base])
num = num / base
stack.reverse()
return "".join(stack)

testword=""
secretword = "daved"
counter = 1L #long
starttime = time.clock()
print "Running..."
while (testword<>secretword):
testword=ntb(counter,26)
counter = counter+1
endtime = time.clock()
print "Secret word: " + testword + " found after " + str(counter) +" attempts"
print "Search took: " + str(round(endtime-starttime,3)) + " seconds"


VB.NET

Not sure if this compiles

Dim secretString As String = "da"

Dim tryString

MessageBox.Show("Starting crypto search.")



Dim i As Integer

For i = 97 To 122



Dim j As Integer

For j = 97 To 122

tryString = Chr(i) + Chr(j)

If tryString = secretString Then

MessageBox.Show("Found secretString which is " & tryString)

End If

Next ' Next j loop

Next ' Next i loop



MessageBox.Show("End crypto and last tryString is " & tryString)

| | #