If there’s a reasonable chance Feynman Cipher #2 (“F2”) is an exotic transposition cipher, it struck me that it might be a good idea to apply a whole load of exotic transpositions, and then use a really simple test to try to order them according to some minimized metric.
The metric I chose was the number of unique letter pairs appearing in the transposed cipher, simply because even a Vigenere should respond to that (for a reasonable-sized cipher). So… here is the bit of C code I wrote:-
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
const char F2[] = /* Note: 261 = 9 * 29 */
"XUKEXWSLZJUAXUNKIGWFSOZRAWURO"
"RKXAOSLHROBXBTKCMUWDVPTFBLMKE"
"FVWMUXTVTWUIDDJVZKBRMCWOIWYDX"
"MLUFPVSHAGSVWUFWORCWUIDUJCNVT"
"TBERTUNOJUZHVTWKORSVRZSVVFSQX"
"OCMUWPYTRLGBMCYPOJCLRIYTVFCCM"
"UWUFPOXCNMCIWMSKPXEDLYIQKDJWI"
"WCJUMVRCJUMVRKXWURKPSEEIWZVXU"
"LEIOETOOFWKBIUXPXUGOWLFPWUSCH";
#define WIDTH 29
#define HEIGHT 9
int count_unique_pairs(const char *cipher, const int * order)
{
int i, j, n;
int curr, last;
int count[26][26];
memset(count, 0, sizeof(count));
n = 0;
curr = -1;
for (i = 0; i < WIDTH; i++)
{
for (j = 0; j < HEIGHT; j++)
{
last = curr;
curr = cipher[order[j]*WIDTH+i] - 'A';
if ((last >= 0) && (count[last][curr]++ == 0))
n++;
}
}
return n;
}
int best_pair_count = 10000000;
void find_order_with_least_unique_pairs(const int * old_order, int index)
{
if (index < HEIGHT)
{
int new_order[HEIGHT];
int i;
for (i = index; i < HEIGHT; i++)
{
memcpy(new_order, old_order, sizeof(new_order));
new_order[index] = old_order[i];
new_order[i] = old_order[index];
find_order_with_least_unique_pairs(new_order, index + 1);
}
}
else
{
int count = count_unique_pairs(F2, old_order);
#if 0
if (count > 188)
return;
#else
if (count > best_pair_count)
return;
#endif
best_pair_count = count;
printf("pairs = %d, order = { %d %d %d %d %d %d %d %d %d }\n",
count,
old_order[0], old_order[1], old_order[2],
old_order[3], old_order[4], old_order[5],
old_order[6], old_order[7], old_order[8]);
}
}
const int default_order[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int main(int argc, char argv[])
{
find_order_with_least_unique_pairs(default_order, 0);
return 0;
}
It didn't reveal a great deal (and pasting it into WordPress lost all the formatting, *sigh*), but I thought I'd post it here anyway. 🙂
Nick,
Do you think this is a transposition, given the sequence on the second last line: “CJUMVRCJUMVR”..
Two six letter sequences side by side in a transposition would be hard to imagine IMO. Even the four letter repeat of WUID is remote when you start to juggle the text columns and/or rows.
I’m coming in late on your post so maybe I misunderstood some angle here.
Cheers,
TT
Tim T: thanks for dropping by, and you’re absolutely right that there’s a CJUMVR repeat. To me, that points to one of two possibilities: (a) it is (after all) a straightforward substitution cipher (but the letter instance stats don’t seem to support this), or (b) this is a copying error, and CJUMVR should only appear once.
I suspect the latter is more likely to be true, and so perhaps the ciphertext should be six characters shorter (261 – 6 = 255, i.e. 3 x 5 x 17).
Cue yet more head-scratching… 🙂