program: EverCrack

  purpose: Substitution Cipher Cracker

  version: v1.0

  creator: Dr MindHacker [Cory Michael Boston]

  contact: drmindhaxor VIA yahoo D0T com


error_reporting(0);

define("TRUE",  1);

define("FALSE",  0);

define("MAX",  32);

define("WORDS",  4096);

define("VALID", 1);

define("INVALID", 0);

define("OPEN", 1);

define("CLOSED", 0);

define("KEEP",  0);

define("DUP",  1);

define("SKIP",  2);

define("BIG",  0);

define("SMALL",  1);

define("REPEATS",  0);

define("UNIQUES",  1);

define("EXHAUSTED", 0);

define("TOO_FEW", 1);

define("SUFFICIENT", 2);

define ("NO_DECODES", 1);

$cword[][] = "";

$pword[][] = "";

$force = 0;

global $lists;

global $lens;

$cpairs[] = "";

global $syms;

global $seq;

global $lang;

global $lex;

$lex = BIG;

/************************************************

 extract the cipher word sequence pattern for

 later analysis

************************************************/

function ExtractPatterns()

  { 

    global $syms;

    global $cpairs;

    global $cword;

    global $lens;

    global $seq;

    for($x = 0; $x < $syms; $x++)

      {

        $seq[$x] = $x;

        $length = ($lens[$x] - 1);

        for($outer = 0; $outer < $length; $outer++)

          {

             for($inner = ($outer + 1); $inner < $lens[$x]; $inner++)

               {  

                 if($cword[$x][$outer] == $cword[$x][$inner])

		   {  $cpairs[$x]++;  }

                }

            }

        }
  
  }

/************************************************

 reset flag to USE

************************************************/

function InitKernel()

  {

   $x = 0;

    for($x = 0; $x < WORDS; $x++)

      {  $flag[$x] = KEEP;  }

  }

/************************************************

 re-order for optimization or if a cipher word

 is found with no pattern match

************************************************/

function SwapWords($x, $y)

  {

    $temp = 0;

    $buf[MAX];

    global $cpairs;
 
    global $seq;

    global $cword;

    global $lens;

    global $flag;


    $temp = $cpairs[$x];

    $cpairs[$x] = $cpairs[$y];

    $cpairs[$y] = $temp;


    $temp = $seq[$x];

    $seq[$x] = $seq[$y];

    $seq[$y] = $temp;


    $buf = $cword[$x];

    $cword[$x] = $cword[$y];

    $cword[$y] = $buf;


    $temp = $lens[$x];

    $lens[$x] = $lens[$y];

    $lens[$y] = $temp;


    $temp = $flag[$x];

    $flag[$x] = $flag[$y];

    $flag[$y] = $temp;

  }

/************************************************

 shift words - move words one position to the

 left

************************************************/

function ShiftWords()

  {

    $x = 0;

    global $words;

    global $cpairs;

    global $seq;

    global $lens;

    global $flag;

    global $cword;

    $y = ($words - 1);

    $tpairs = $cpairs[0];

    $tseq = $seq[0];

    $tlens = $lens[0];

    $tflag = $flag[0];

    $tword = "";

    $tword = $cword[0];

    for($x = 0; $x < $y; $x++)

      {

        $cpairs[$x] = $cpairs[$x + 1];

        $seq[$x] = $seq[$x + 1];

        $lens[$x] = $lens[$x + 1];

        $flag[$x] = $flag[$x + 1];

        $cword[$x] = $cword[$x + 1];

      }

    $cpairs[$y] = $tpairs;

    $seq[$y] = $tseq;

    $lens[$y] = $tlens;

    $flag[$y] = $tflag;

    $cword[$y] = $tword;

  }

/************************************************

 re-sequence the cipher text by length in order

 to create the most incosistent results at

 the beginning of the consistency checks, thus

 reducing the total number of comparisons

************************************************/

function Resequence()


  {

    $x = 0;

    $y = 0;

    global $syms;

    global $lens;

    global $flag;

     for($x = 0; $x < ($syms - 1); $x++)

       {

          for($y = ($x + 1); $y < $syms; $y++)

            {

	      if(($lens[$x] < $lens[$y])  && ($flag[$y] == KEEP))

                {  SwapWords($x, $y);  }

            }

       }

  }

/************************************************

 check to see if any cipher words have been

 flagged to be skipped and push to end of

 cipher word list - cipher words are flagged to

 be skipped if their cipher pattern generates

 no clear patterns or if the word caused an

 inconsistency block during the consistency

 checks (i.e., word missing from dictionary)

************************************************/

function SkipCheck()

  {

    $x = 0;

    global $syms;

    global $flag;

    $end = ($syms - 1);

    for($x = 0; $x < $end; $x++)

      {

        if($flag[$x] != KEEP)

          {

            while($flag[$end] != KEEP)


	      {  $end--;  }


	    if($end > $x)

	      {  SwapWords($x, $end);  }

          }

      }

  }

/************************************************

 check to see if there is a word list that fits

 this pattern


************************************************/

function CheckPattern($x)

  {

    $flag[$x] = KEEP;

    global $lists;

    global $flag;

    if(file_exists($lists[$x]) == FALSE)

      {  $flag[$x] = SKIP;  }

    return $flag[$x];

  }

/************************************************

 store appropriate dictionary lists for each

 cipher word according to its pattern

************************************************/

function StoreLists($x)

  {

     global $lists;

     global $cpairs;

     global $lens;

     global $lex;

     global $lang;

    $buf[32];

    $lists[$x] = "dict/";

    switch($lang)

      { 

        case "English":

          $lists[$x] .= "eng/";

          break;

        case "German":

           $lists[$x] .= "ger/";

          break;

        case "French":

           $lists[$x] .= "fre/";

          break;

        case "Spanish":

          $lists[$x] .= "spa/";

          $lex = BIG;

          break;

        case "Italian":

          $lists[$x] .= "ita/";

          $lex = BIG;

          break;

        case "Swedish":

          $lists[$x] .= "swe/";

          $lex = BIG;

          break;

        case "Dutch":

          $lists[$x] .= "dut/";

          $lex = BIG;

          break;

        case "Portugeuse":

          $lists[$x] .= "por/";

          break;

      } 

    if($lex == BIG)

     {  $lists[$x] .= "big/";  }

    else

      {  $lists[$x] .= "small/";  }

   $lists[$x] .= $lens[$x];

    if($cpairs[$x] > 0)

      {

        $lists[$x] .= "P";

	$lists[$x] .= $cpairs[$x];  

      }

   else

      {  $lists[$x] .= "N";   }

    $lists[$x] .= ".TXT";

    return CheckPattern($x);

  }

/************************************************

 parses words of cipher text

************************************************/

function GetStats()

  {

    global $syms;

    global $cword;

    global $lens;

    global $lex;

    global $lang;

    $alphas = "abcdefghijklmnopqrstuvwxyz";

    $lang = $_POST['LANG'];

    $force = $_POST['DICT'];

    $log = fopen("inlog.txt", "a");

    fprintf($log, "%s\n%s\n\n", $lang, $_POST['CIPHER']);

    fclose($log);    

    $cword = preg_split("/[\s]+/", $_POST['CIPHER']);   

    $syms = count($cword);

    for($x = 0; $x < $syms; $x++)

      {
   
        $cword[$x] = 

        preg_replace

        ('/([0-9]+)|!|@|#|%|&|-|_|=|,|:|;|<|>|`|~|"|\/|\'|\||\.|\[|\]|\{|\}|\+|\(|\)|\*|\^|\$|\?|\\\/i', '', $cword[$x]);

        $lens[$x] = strlen($cword[$x]);

        $cword[$x] = strtolower($cword[$x]);     

      } 

    if(($syms == 1) && ($lens[0] > 20))

      {

        //echo 'Ciphertext must contain word divisions!';
 
        exit(0);

      }

    if(($syms < 20) && ($force[0] != 'L'))

      {  $lex = SMALL;  }

  }


/************************************************

 check to see if word from dictionary list

 matches the pattern of the cipher word

************************************************/

function FindPattern($sym, $pword)

  {

    $x = 0;

    $y = 0;

    global $lens;

    global $syms;

    global $pword;

    global $cword;

    $len = ($lens[$sym] - 1);

    for($x = 0; $x < $len; $x++)

      {

        for($y = ($x + 1); $y < $lens[$sym]; $y++)


          {

            if((($pword[$sym][$x] == $pword[$sym][$y]) &&

                ($cword[$sym][$x] == $cword[$sym][$y]))

               ||

              (($cword[$sym][$x] != $cword[$sym][$y]) &&

                ($pword[$sym][$x] != $pword[$sym][$y])))

		{  continue;  }

            else

              {   return SKIP;  } 

          }

      }

    return KEEP;

  }

/************************************************

 compare the consistency of cipher-to-plain and

 plain-to-cipher patterns - compares cipher-to

 plain first then plain-to-cipher, if the two   550

 words do not have cipher letters in common

 it checks to see if they do have plain letters

 in common to rule out as invalid

************************************************/

function XComparePatterns($src, $trg)

  {

    global $cword;

    global $pword;

    global $lens; 

    for($src = 0; $src < $trg; $src++)

      {

        for($x = 0; $x < $lens[$src]; $x++)

          {

            for($y = 0; $y < $lens[$trg];  $y++)

              { 

                if(($cword[$src][$x] == $cword[$trg][$y]) xor ($pword[$src][$x] == $pword[$trg][$y]))

                  {  return INVALID; }

              }

          } 

      }

    return VALID;


  }


/************************************************

 partially decrypt skipped word by going thru


 each letter of each cipher word and if it is

 common with letter in cipher word flagged

 as SKIP | DUP then assign the corresponding

 clear word letter to that position - only goes

 through enough times for each letter of cipher

 cipher word flagged as SKIP | DUP

************************************************/

function PartialDecrypt($y)

  {

    $sym = 0;

    $letter = 0;

    $flagged = 0;

    $matching = TRUE;

    $matches = 0;

    global $cword;

    global $pword;

    global $lens;

    global $words;

    $pword[$y] = strtoupper($cword[$y]);

    $sym = 0;

    while($matching == TRUE)

      { 

        if($cword[$y][$flagged] == $cword[$sym][$letter])

          {  

	    $pword[$y][$flagged] = $pword[$sym][$letter];

            $flagged++;

            $matches++;

          }

        if(++$letter == $lens[$sym])

          {

            $letter = 0;

            $sym++;

            if($sym == $words)

              {

                if($matches > 0)

                  {  $matches = 0;  }

                else

                  {  $flagged++;  }

                $sym = 0;

              }

          }

        if($flagged > $lens[$y])

          {  $matching = 0;  }

      }

    //echo $pword[$y], ' ';

  }

/************************************************

 write decodes and partially decrypt any words

 flagged as skipped [words that had no pattern

 matches in lexicon]

************************************************/

function WriteDecodes()

  {

    $x = 0;

    $y = 0;

    $z = 0;

    global $decodes;

    global $syms;

    global $seq;

    global $flag;

    global $pword;

    $decodes++;

    //echo "[$decodes] ";

    for($x = 0; $x < $syms; $x++)       

      {

        for($y = 0; $y < $syms; $y++)

          {

	    if($x == $seq[$y])

	      {

                switch($flag[$y])

                  {

                    case KEEP:

		      //echo $pword[$y], ' ';

                      break;

		   default:

                      PartialDecrypt($y);

                      break;

                  }

                $z++;

                if($z == 20)

                 {   

                      //echo '\n';

                      $z = 0;

                  }

              }

          }

      }

  }

/**************************************************

 open prev

**************************************************/

function OpenPrev(&$trg, &$list, &$stat, &$pos)

  { 

    fclose($list);

    $stat[$trg] = CLOSED;

    $pos[$trg] = 0;

    return --$trg;

  }


/**************************************************

 open next

**************************************************/

function OpenNext(&$trg, &$list, &$stat, &$pos)

  {

    $pos[$trg] = ftell($list);

    fclose($list);  

    $stat[$trg] = CLOSED;

    return ++$trg;

  }

/**************************************************

 deep analysis opens each word list [of lexical

 words matching the patterns of each cipher-word]

 and performs cross-consistency-checks [compare

 cipher-to-clear and clear-to-cipher decodes]

 forward and backwards through the lists until

 all possible translations are exhausted.

**************************************************/

function ComparePatterns()


  {

    $pos[] = ( 0 );

    $stat[] = CLOSED;

    $src = 0;

    $trg = 1;

    $comparing = TRUE;

    $searching = TRUE;

    global $cword;

    global $pword;

    global $lens;
 
    global $lists;

    global $cpairs;

    global $words;

    $master = fopen($lists[$src], "r");

    while($comparing == TRUE)

      { 

        $pword[$src] = fgets($master);

        if(feof($master))

          { 

            fclose($master);

            $comparing = FALSE;

            continue;

          }
       
        rtrim($pword[$src]);

        if(($cpairs[$src] > 0) && (FindPattern($src, $pword) == SKIP))

	  {  continue;  }

        $trg = 1;

        $stat[$trg] = CLOSED;

        $searching = TRUE;

        while($searching == TRUE)

          {

            if($stat[$trg] == CLOSED)

              {

	        $list = fopen($lists[$trg], "r");

                $stat[$trg] = OPEN; 

                fseek($list, $pos[$trg], SEEK_SET);

              }

            $pword[$trg] = fgets($list);

            rtrim($pword[$trg]);

            if(feof($list))

	      { 

	        $trg = OpenPrev(&$trg, &$list, &$stat, &$pos);

                if($trg == $src) 

                  {  $searching = FALSE;  }

                continue;

              }

            else

              {		 

		 if(($cpairs[$trg] > 0) && (FindPattern($trg, $pword) == SKIP))

		   {  continue;  }

                else

		  {

                    if(XComparePatterns($src, $trg) == VALID)

                      { 
		        
                        if($trg < ($words - 1))

			  {  $trg = OpenNext(&$trg, &$list, &$stat, &$pos);  }

                        else

			  {  WriteDecodes();  }

                      }

                  }

              }

          }

      }

    return 0;

  }

/************************************************

 only one word in cipher, just insert plain

 word matches into edit

************************************************/

function InsertList()

  {

    global $pword;

    global $lens;
 
    global $cpairs;

    global $lists; 

    $inserting = TRUE;

    $in = fopen($lists[0], "r");

    if($in)

      { 

        while($inserting)

          {

            $pword[0] = fgets($in);

            if(feof($in))

              {  $inserting = FALSE;  }

            else

              {

	       rtrim($pword[0]);

	        if(($cpairs[0]) && (FindPattern(0, $pword[0]) == SKIP))

	          {  continue;  }

	        else

	          {  WriteDecodes();  }

              }

          }

       fclose($in);

      }

    else

      {  

        //echo "Could not open $lists[0][0]";  

        exit(0);

      }

  }

/************************************************

 figure out which words are the only ones

 necessary to account for all cipher symbols

 in the cipher text - this will minimize the

 number of words we have to actually crypt-

 analyze

************************************************/

function CheckSymbols()

  {

    $alphabet[] = 0;

    $xsymbols[][] = 0;

    $x = 0;

    $y = 0;

    $dups = 0;

    $symbol = 0;

    global $syms;

    global $cword;

    global $lens;

    global $flag; 

    global $words;

    for($x = 0; $x < $syms; $x++)

      {

        if($flag[$x] != SKIP)

	  {

	    for($y = 0; $y < $lens[$x]; $y++)

	      {

		 $symbol = $cword[$x][$y];

                 if($alphabet[$symbol] == 0)

		  {

		    $alphabet[$symbol] = 1;

		    $xsymbols[UNIQUES][$x]++;

		  }
 
	       else

		 {  $xsymbols[REPEATS][$x]++;  }

              }

            if($xsymbols[UNIQUES][$x] == 0)

             {

	        $flag[$x] = DUP;

	        $words--;

	        $dups++;

              }

          }

      }

    return $dups; 

  }

/************************************************

 optimize

************************************************/

function Optimize()

  {

    $x = 0;

    $skips = 0;

    $result = 0;

    $tries = 0;

    $dups = 0;

    $start = 0;

    global $syms;

    global $flag;

    global $words;

    $optimizing = TRUE;

    while($optimizing == TRUE)

      { 

	 $skips = 0;

	 $dups = CheckSymbols();

	 if(($dups) || ($words == 1))

	   {

	     SkipCheck();

	     Resequence();

	   } 


	for($x = 0; $x < $words; $x++)


	  {

	    if(StoreLists($x) == SKIP)


	      { $skips++;  $skipped++;  }


	  }

	if($skipped == $syms)


	  {  return EXHAUSTED; }

	 if($skips > 0)

	  {

	    $start = $words;

	    $words -= $skips;

	    for($x = $start; $x < $syms; $x++)

	      {

		 if($flag[$x] == DUP)

		  {

		    $flag[$x] = KEEP;

		    $words++;

		  }

	       }

           }

        else

          {  $optimizing = FALSE;  }

      }

    if($words == 1)

      {  return TOO_FEW;  } 

    return SUFFICIENT;

  }

/************************************************

 gather information about ciphertext for analysis

************************************************/

function AnalyzeCipherText()

  {

    global $decodes;

    global $flag;

    global $words;

    global $syms;

    $words = $syms;

    Resequence();

    if(Optimize() == EXHAUSTED)

      { return EXHAUSTED;  }

    else if($words == 1)

      { 

        InsertList();

	 if(!$decodes)

	   {

	     if($flag[1] == SKIP)

	       {  return EXHAUSTED;  }

	     else

		{

		   $flag[1] = KEEP;

		   $flag[0] = DUP;

		   StoreLists(1);

	           SwapWords(0,1);

		    InsertList();

		    if(!$decodes)

		     {  return EXHAUSTED;  }

                 }

          }

        return TOO_FEW;

      }

    return SUFFICIENT;

  }

/************************************************

 attack monoalphabetic substitution cipher

************************************************/

function CrackCipher()

  {

    $result = TOO_FEW;

    global $lex;

    global $decodes;

    global $flag;

    global $words;

    global $syms; 

    if(($syms == 1) || (($syms < 3) &&($lens[1] == 0))) // debug this shit!!!

      { 
 
        $result = StoreLists(0);

        if($result == SKIP)

         // {  echo "No words match that pattern!";  }

        else

          {  

            InsertList();  

            if(!$decodes)

              // {  echo "No words match that pattern!";  }

          }

      }

    else

      {

        $result = AnalyzeCipherText();

        if($result == SUFFICIENT)

          {

            $x = 0;

	    $analyzing = TRUE;

	    $attempts = 0;

	    $start;

	    $start = time();

            while($analyzing == TRUE)

	      {

	        if(ComparePatterns() == NO_DECODES)

	          { ; }

	        if(($decodes < 1) && ($lex == SMALL))

	          {  

		    $lex = BIG;

		    AnalyzeCipherText();

                    continue;

	          }

	        if($decodes > 0)

	          { 

                    $analyzing = FALSE;

                    continue;

                  }


	       else

	         {

                    if($attempts == $words)

		      {  

		         if($flag[0] != SKIP)

		           {  

			      for($x = 1;$x < $words; $x++)

			       {  $flag[$x] = SKIP; }

			      InsertList();

		           }

		       $analyzing = 0;

                     }

	           else

		     { 

		        if($attempts != 0)

		          {  $words++; }


		       $flag[0] = SKIP;

		       $flag[$words - 1] = KEEP;

                        ShiftWords();

		         for($x = 0; $x < $words; $x++)
 
                           { StoreLists($x); }

		        $words--;

		        $attempts++;

                      }


                  }

              }

           }

        else

         {  return $result;  }

         $finish = time();

        $elapsed = $finish - $start;

        //echo 'Words:    ', $syms'; 

        //echo 'Decodes:  ', $decodes';

        //echo 'Time:     ', $elapsed';

        return $result;

      }

  }

GetStats();

InitKernel();

ExtractPatterns();

CrackCipher();

[Return to EverCrack Main]