int main( int argc, char * argv[] ) { char from[10] = "aablls?"; if( argc >= 2 ) { std::string arg(argv[1]); std::sort( arg.begin(), arg.end() ); strcpy( from, arg.c_str() ); } if( argc >= 3 ) { min_length = atoi( argv[2] ); } logf( 1, CLEAR "Score %s -> %i\n", from, ScoreString( from ) ); const int MAX_LEN = 32; int lengths[MAX_LEN] = {0}; if( FILE * fp = fopen( "enable1.txt", "rt" ) ) { double start = PerfTime(); while( !feof( fp ) ) { char buf[MAX_LEN]; char * got = fgets( buf, 63, fp ); if( got ) { char *end = buf + strlen(buf) -1; while( end > buf && !isalpha( *end ) ) { *end = 0; end -= 1; } int l = strlen(buf); lengths[l] += 1; if( l <= 15 ) { words.push_back(std::string(buf)); } } } double loaded = PerfTime(); double runTime = PerfTime(); Words gathered = GatherAngrams( from ); std::sort( gathered.begin(), gathered.end(), XScoresLessThanY ); for( auto s : gathered ) { logf( 1, CLEAR "%s - %i\n", s.c_str(), ScoreString( s ) ); } double done = PerfTime(); logf( 1, CLEAR "Timing (%f s) Loading\n", loaded-start ); //logf( 1, CLEAR "Timing (%f s) Preparing\n", prepared-prepping); logf( 1, CLEAR "Timing (%f s) running\n", done-runTime ); } return 0; }
// NOTE(brendan): INPUT: Ciphertext in ASCII-256, length of ciphertext. // OUTPUT: string with max score based on frequency analysis, and from trying // all byte ciphers uint8 ByteCipherAsciiDecode(char *DecodedString, char *Ciphertext, uint32 CipherLength) { char Key[CipherLength + 1]; Key[CipherLength] = 0; // NOTE(brendan): decrypt real32 MinScore = INFINITY; uint32 MinCipher = 0; // TODO(brendan): calculate frequencies and subtract from expected // frequencies; maximize that value for (uint32 ByteCipher = 0; ByteCipher < 256; ++ByteCipher) { CreateAsciiKey(Key, ByteCipher, CipherLength); XORAsciiStrings(DecodedString, Key, Ciphertext, CipherLength); for (uint32 CipherIndex = 0; CipherIndex < CipherLength; ++CipherIndex) { DecodedString[CipherIndex] = Key[CipherIndex] ^ Ciphertext[CipherIndex]; } real32 Score = ScoreString(DecodedString, CipherLength); if (Score < MinScore) { MinScore = Score; MinCipher = ByteCipher; } } CreateAsciiKey(Key, MinCipher, CipherLength); XORAsciiStrings(DecodedString, Key, Ciphertext, CipherLength); return MinCipher; }
// NOTE(brendan): INPUT: Ciphertext in hex, length of ciphertext. // OUTPUT: string with max score based on frequency analysis, and from trying // all byte ciphers real32 ByteCipherInHexDecode(char *DecodedString, char *Ciphertext, uint32 CipherLength) { uint32 DecodedStringLength = CipherLength/2 + 1; char Key[CipherLength + 1]; // NOTE(brendan): decrypt real32 MinScore = INFINITY; uint32 MinCipher = 0; char XORResult[CipherLength + 1]; // TODO(brendan): calculate frequencies and subtract from expected // frequencies; maximize that value for (uint32 ByteCipher = 0; ByteCipher < 256; ++ByteCipher) { CreateKey(Key, ByteCipher, CipherLength); XORStrings(XORResult, Key, Ciphertext, CipherLength); DecodeHexString(DecodedString, XORResult, CipherLength); real32 Score = ScoreString(DecodedString, DecodedStringLength - 1); if (Score < MinScore) { MinScore = Score; MinCipher = ByteCipher; } } CreateKey(Key, MinCipher, CipherLength); XORStrings(XORResult, Key, Ciphertext, CipherLength); DecodeHexString(DecodedString, XORResult, CipherLength); return MinScore; }
int GetEntireScore(char* inp, int leng) { int sc=0; for (int i=0; i<leng; i++) { for (int j=i+1; j<leng; j++) { sc += ScoreString(inp,i,j); } } return sc; }
bool XScoresLessThanY( const std::string &x, const std::string &y ) { int xScore = ScoreString( x ); int yScore = ScoreString( y ); return xScore < yScore; }