Cool! Then you've got it down pat -- congratulations on solving the known-plaintext problem.

Actually, you solved a more generic, and very valuable, problem: solving for the alphabets given any plaintext. You may be able to speed up your algorithm by about two magnitudes by selecting the best plaintext for the job. Here's an explanation of the method I used.

(2) The next (pt,ct) pair is (L,L). Since neither the left nor the right alphabets have an 'L' in them (what I call a 'hole' for lack of a better name) we iterate through the empty slots in the alphabets, recursively trying (L,L) in each position. Permute the alphabets.

(3) The next pair is (L,Y). Since the right (pt) alphabet has an 'L' we get a free ride and can insert the 'L' in the right alphabet.

(4) The next pair is (G,T), This is a hole, so we recursively insert it in the empty slots in the alphabets. This is the second nested recursion.

(5) The next pair is (O,Z), again a hole, so we recurse for the third time.

When we have reached the 86th pair, we have identified all 26 letters in both the left and right alphabets (technically we only need to identify 25 letters in each alphabet, in which case we implicitly know the 26th, but waiting to find all 26 is just cleaner algorithmically

).

It turns out that using these first 86 pt/ct letters means dealing with 14 holes:

The bottom line is that there are 14 nested recursions, requiring approximately 26x25x24...x14 = 64,764,752,532,480,000 combinations (this may be less because of diminishing empty slots, but you get the idea).

I wrote a simple program to locate sequences of plaintext/ciphertext in Exhibit 1 that (a) account for all 26 letters in both alphabets, and (b) gives the minimal number of holes. Here's the output:

wrote:Found! (length: 86, #holes: 14, len(ptAlph)=26 len(ctAlph)=26)

PT: ALLGOODQQUICKBROWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOX

ESJUMPOVER

CT: CLYTZPNZKLDDQGFBOOTYSNEPUAGKIUNKNCRINRCVKJNHTOAFQPDPNCVLTVFICOTSSLWYYIHBICFU

THXNUVKGIM

Hole Data:

1, (pt,ct)=(L,L)

3, (pt,ct)=(G,T)

4, (pt,ct)=(O,Z)

6, (pt,ct)=(D,N)

10, (pt,ct)=(I,D)

12, (pt,ct)=(K,Q)

13, (pt,ct)=(B,G)

14, (pt,ct)=(R,F)

16, (pt,ct)=(W,O)

20, (pt,ct)=(X,S)

22, (pt,ct)=(S,E)

25, (pt,ct)=(M,A)

28, (pt,ct)=(V,I)

34, (pt,ct)=(Y,R)

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

Found! (length: 70, #holes: 13, len(ptAlph)=26 len(ctAlph)=26)

PT: OXESJUMPOVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZ

CT: YSNEPUAGKIUNKNCRINRCVKJNHTOAFQPDPNCVLTVFICOTSSLWYYIHBICFUTHXNUVKGIMVEZ

Hole Data:

20, (pt,ct)=(X,S)

21, (pt,ct)=(E,N)

22, (pt,ct)=(S,E)

23, (pt,ct)=(J,P)

24, (pt,ct)=(U,U)

25, (pt,ct)=(M,A)

26, (pt,ct)=(P,G)

28, (pt,ct)=(V,I)

33, (pt,ct)=(Z,C)

34, (pt,ct)=(Y,R)

45, (pt,ct)=(H,O)

47, (pt,ct)=(I,F)

66, (pt,ct)=(C,W)

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

Found! (length: 66, #holes: 12, len(ptAlph)=26 len(ctAlph)=26)

PT: JUMPOVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZ

CT: PUAGKIUNKNCRINRCVKJNHTOAFQPDPNCVLTVFICOTSSLWYYIHBICFUTHXNUVKGIMVEZ

Hole Data:

24, (pt,ct)=(U,U)

25, (pt,ct)=(M,A)

26, (pt,ct)=(P,G)

27, (pt,ct)=(O,K)

28, (pt,ct)=(V,I)

30, (pt,ct)=(R,N)

33, (pt,ct)=(Z,C)

34, (pt,ct)=(Y,R)

45, (pt,ct)=(H,O)

47, (pt,ct)=(I,F)

66, (pt,ct)=(C,W)

67, (pt,ct)=(K,Y)

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

Found! (length: 63, #holes: 11, len(ptAlph)=26 len(ctAlph)=26)

PT: POVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZ

CT: GKIUNKNCRINRCVKJNHTOAFQPDPNCVLTVFICOTSSLWYYIHBICFUTHXNUVKGIMVEZ

Hole Data:

27, (pt,ct)=(O,K)

28, (pt,ct)=(V,I)

29, (pt,ct)=(E,U)

30, (pt,ct)=(R,N)

33, (pt,ct)=(Z,C)

34, (pt,ct)=(Y,R)

45, (pt,ct)=(H,O)

47, (pt,ct)=(I,F)

66, (pt,ct)=(C,W)

67, (pt,ct)=(K,Y)

78, (pt,ct)=(J,X)

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

Found! (length: 97, #holes: 10, len(ptAlph)=26 len(ctAlph)=26)

PT: ROWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZY

DOGTOSAVETHEIRPARTYWA

CT: SYYHZUVLFFURRHRIIFFDZMTTOVKLZOVLPVPPGVGEWWEFRFYHKXOPKXRQSZKLCZKHZWXRJXLMVFGG

FGYIFDAEINIWPOMOUVRFB

Hole Data:

290, (pt,ct)=(O,Y)

292, (pt,ct)=(N,H)

293, (pt,ct)=(F,Z)

295, (pt,ct)=(X,V)

296, (pt,ct)=(E,L)

297, (pt,ct)=(S,F)

300, (pt,ct)=(M,R)

308, (pt,ct)=(Z,D)

310, (pt,ct)=(D,M)

313, (pt,ct)=(T,O)

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

Found! (length: 96, #holes: 9, len(ptAlph)=26 len(ctAlph)=26)

PT: OWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZYD

OGTOSAVETHEIRPARTYWA

CT: YYHZUVLFFURRHRIIFFDZMTTOVKLZOVLPVPPGVGEWWEFRFYHKXOPKXRQSZKLCZKHZWXRJXLMVFGGF

GYIFDAEINIWPOMOUVRFB

Hole Data:

292, (pt,ct)=(N,H)

293, (pt,ct)=(F,Z)

295, (pt,ct)=(X,V)

296, (pt,ct)=(E,L)

297, (pt,ct)=(S,F)

300, (pt,ct)=(M,R)

308, (pt,ct)=(Z,D)

310, (pt,ct)=(D,M)

313, (pt,ct)=(T,O)

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

Found! (length: 82, #holes: 8, len(ptAlph)=26 len(ctAlph)=26)

PT: ERLAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRP

ARTYWA

CT: IIFFDZMTTOVKLZOVLPVPPGVGEWWEFRFYHKXOPKXRQSZKLCZKHZWXRJXLMVFGGFGYIFDAEINIWPOM

OUVRFB

Hole Data:

306, (pt,ct)=(L,F)

308, (pt,ct)=(Z,D)

309, (pt,ct)=(Y,Z)

310, (pt,ct)=(D,M)

311, (pt,ct)=(O,T)

313, (pt,ct)=(T,O)

315, (pt,ct)=(S,K)

329, (pt,ct)=(W,W)

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

Found! (length: 80, #holes: 7, len(ptAlph)=26 len(ctAlph)=26)

PT: LAZYDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRPAR

TYWA

CT: FFDZMTTOVKLZOVLPVPPGVGEWWEFRFYHKXOPKXRQSZKLCZKHZWXRJXLMVFGGFGYIFDAEINIWPOMOU

VRFB

Hole Data:

308, (pt,ct)=(Z,D)

309, (pt,ct)=(Y,Z)

310, (pt,ct)=(D,M)

311, (pt,ct)=(O,T)

313, (pt,ct)=(T,O)

315, (pt,ct)=(S,K)

329, (pt,ct)=(W,W)

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

Found! (length: 77, #holes: 6, len(ptAlph)=26 len(ctAlph)=26)

PT: YDOGTOSAVETHEIRPARTYWALLGOODQQUICKBROWNFOXESJUMPOVERLAZYDOGTOSAVETHEIRPARTYW

A

CT: ZMTTOVKLZOVLPVPPGVGEWWEFRFYHKXOPKXRQSZKLCZKHZWXRJXLMVFGGFGYIFDAEINIWPOMOUVRF

B

Hole Data:

310, (pt,ct)=(D,M)

311, (pt,ct)=(O,T)

313, (pt,ct)=(T,O)

315, (pt,ct)=(S,K)

316, (pt,ct)=(A,L)

329, (pt,ct)=(W,W)

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

Found! (length: 198, #holes: 5, len(ptAlph)=26 len(ctAlph)=26)

PT: EANDEQUALSTATIONTOWHICHTHELAWSOFNATUREANDOFNATUREXSGODENTITLETHEMQADECENTRES

PECTTOTHEOPINIONSOFMANKINDREQUIRESTHATTHEYSHOULDDECLARETHECAUSESWHICHIMPELTHEMTO

THESEPARATIONZWEHOLDTHESETRUTHSTOBESELFJEV

CT: FFQBVLDYYBBQTLBAOWLOZSDYZFQECGTATTDSEXFVKJAYYVNUQWYZXXDYLGVXZPXOGLZRBZNMXFFW

NUCTFXKVFBSPUMKMJSAEVBPKLBQOYMJRXQJQGRHSQKYYKISZUOEEDCYRQPHZJCDIRIKQFRLTOBPLDBOL

WBVLJHJNRJUYYFPUOXMQELBIHKWFFWUPOKOOKHZMPR

Hole Data:

5929, (pt,ct)=(N,Q)

5930, (pt,ct)=(D,B)

5932, (pt,ct)=(Q,L)

5933, (pt,ct)=(U,D)

5948, (pt,ct)=(C,S)

This simple program found that the plaintext starting at offset 5929 and having a length of 198 characters ("EANDEQUALSTATIONTOWHICHTHELAWS...") gives all 26 letters in both alphabets with only five (5) holes, meaning only five nested recursions. Thus, at most the program will need to text 26x25x24x23x22 = 7,893,600 cases.

Once you've solved for the starting alphabets beginning with offset 5929, you can rewind the alphabets to the beginning (offset 0) by deciphering the known ciphertext (the plaintext for the ciphertext starting with offset 5500 is unknown, so you cannot depend on it).

Having said all of this, there will definitely be times (e.g., using a known or supposed crib) when we cannot choose our plaintext. In that case, the algorithm will just need to examine as many cases as it needs to.

I hope this is clear and that it helps reduce your algorithm's running time.