> load "tut3data.txt"; Loading "L:\win\Magma\MATH2068\tut3data.txt" > V:=VigenereCryptosystem(7); > k:=V!"CARSLAW"; > /* > We have declared V to be a Vigenere Cryptosystem for which the > keyword will have seven letters. The command k:=V!"CARSLAW" > tells magma to take the 7-letter string "CARSLAW", coerce it > into V, and give the result the name k. (The exclamation mark > is magma's coercion operator.) > What this really means is that we will be able to use k as > a keyword for enciphering messages in the cryptosystem V. > */ > M:="Computer Tutorial Three"; > P:=Encoding(V,M); > M; Computer Tutorial Three > P; COMPUTERTUTORIALTHREE > /* > Typing an identifier as a magma command causes magma to > print the value of the identifier. We declared M to be > an identifier whose value is the string "Computer Tutorial Three" > and then set P to be M encoded for our cyrptosystem V. > The encoding process converts all letters to uppercase and > discards everything else. Furthermore, the encoded text is > (in magma's world) no longer a string, but an object of > type CryptTxt. > */ > C:=Enciphering(k,P); > C; EODHFTATTLLZRECLKZCEA > /* > Note first that the ciphertext C has the same number of > letters as the plaintext P. The rule for enciphering is > as follows. First, look at the first letter of the key. > The key is CARSLAW, its first letter is C. Think of this > letter as the key for a translation cipher (or alphabetic > shift). The key for a translation cipher is the letter > that A will be replaced by. Since A is the first letter > of the alphabet and C is the third, an alphabetic shift > that replaces A by C is a shift of two steps: this translation > cipher replaces any letter by the one that comes two steps > after it in the alphabet. We apply this translation cipher > to the first letter of the plaintext (namely C) and the > result is the first letter of the ciphertext (namely E). > Now we move on to the second letter of the keyword > (in this case it is A), regard this as a key for a > translation cipher, and apply this translation cipher to > the second letter of the plaintext. A translation cipher > with key A takes A to A: it therefore shifts everything > zero steps alphabetically. So since the second letter of > the plaintext is O, the second letter of the ciphertext > will be O. Now go on to third letter of the key k, > and apply the corresponding translation cipher to the > third letter of the plaintext. And so on. > */ > Index(alphabet,"R"); 18 > /* > R is the 18th letter of the alphabet; so the translation > cipher with key R shifts everything 17 steps alphabetically. > */ > Index(alphabet,"M"); 13 > /* > This is the third letter of the plaintext. We have to shift > 17 steps alphabetically; this will give us the 30th letter > of the alphabet. To interpret this we say that after Z you > go back to A -- so A is the 27th letter (as well as the 1st), > B the 28th, C the 29th and D the 30th. So the third letter > of the ciphertext is D. > I could get magma to do this calculation, to check that D is > right: > */ > (13+17) mod 26; 4 > /* > Magma's mod function returns the residue of the number it > is applied to. That is, > a mod b > returns the remainder when a is divided by b. > */ > alphabet[4]; D > /* > D is the 4th letter of the alphabet. > Doing all of the above in one command: > */ > alphabet[((Index(alphabet,"R")+Index(alphabet,"M")-2) mod 26)+1]; D > /* > Note that the mod command could have returned the answer 0, and > alphabet[0] is undefined. So, for example, alphabet[a mod 26] > would give an error when a = 26. So instead I have to write > alphabet[((a-1) mod 26)+1], which gives the right answer. > > OK, now let us convert P and k back into strings and do the > Vigenere enciphering by "bare hands", and check that we get > the same answer as the enciphering function gave. > */ > SP:=String(P); > Sk:=String(k); > SP; COMPUTERTUTORIALTHREE > Sk; CARSLAW > for i:=1 to #SP do for> alphabet[((Index(alphabet,Sk[((i-1) mod 7)+1])+Index(alphabet,SP[i])-2) mod 26)+1]; for> end for; E O D H F T A T T L L Z R E C L K Z C E A > C; EODHFTATTLLZRECLKZCEA > /* > Let's be even fancier! > */ > &*[alphabet[((Index(alphabet,Sk[((i-1) mod 7)+1])+Index(alphabet,SP[i])-2) mod 26)+1] \ : i in [1..#SP]]; EODHFTATTLLZRECLKZCEA > /* > That must be pretty much what the enciphering function does! > */ > m:=InverseKey(k); > m; YAJIPAE > k; CARSLAW > /* > The translation cipher corresponding to the i-th letter of k > followed by the translation cipher corresponding to the i-th > letter of m should be the translation cipher that does nothing. > This will ensure that enciphering with m "undoes" enciphering with k. > For example, the third letter of k is R, which is the 18th letter > of the alphabet. So the corresponding translation cipher shifts everything > 17 steps alphabetically. The third letter of m is J, the 10th letter > of the alphabet, corresponding to a 9-step alphabetic shift. > An alphabetic shift of 17 followed by an alpabetic shift of 9 gives > an alphabetic shift of 26, which takes each letter back to itself. > */ > Sm:=String(m); > for i:=1 to #Sk do for> (Index(alphabet,Sk[i])+Index(alphabet,Sm[i])-2) mod 26; for> end for; 0 0 0 0 0 0 0 > Enciphering(m,C); COMPUTERTUTORIALTHREE > > /* > The coincidence index is much higher for typical English text > than it would be for a meaningless string of letters in which > all letters have roughly the same frequency, because in typical > English some letters are very common and some very rare. > The probability that two randomly chosen letters will be > the same is relatively high for English text, because (for > example) there is a pretty good chance they will both be E's, > and a pretty good chance they will both be T's or both A's. > An uneven distribution increases the chance that two randomly > chosen letters are the same. > > The mathematical fact at work here is that if 26 nonnegative > numbers add up to 1 then the smallest possible value > for the sum of the squares of those 26 numbers is 1/26, > and this occurs when they are all equal. > */ > dancemen; Holmes had been seated for some hours in silence with his long, thin back curved over a chemical vessel in which he was brewing a particularly malodorous product. His head was sunk upon his breast, and he looked from my point of view like a strange, lank bird, with dull gray plumage and a black top-knot. "So, Watson," said he, suddenly, "you do not propose to invest in South African securities?" I gave a start of astonishment. Accustomed as I was to Holmes's curious faculties, this sudden intrusion into my most intimate thoughts was utterly inexplicable. "How on earth do you know that?" I asked. He wheeled round upon his stool, with a steaming test-tube in his hand, and a gleam of amusement in his deep-set eyes. "Now, Watson, confess yourself utterly taken aback," said he. "I am." "I ought to make you sign a paper to that effect." "Why?" "Because in five minutes you will say that it is all so absurdly simple." "I am sure that I shall say nothing of the kind." "You see, my dear Watson" -- he propped his test-tube in the rack, and began to lecture with the air of a professor addressing his class -- "it is not really difficult to construct a series of inferences, each dependent upon its predecessor and each simple in itself. If, after doing so, one simply knocks out all the central inferences and presents one's audience with the starting-point and the conclusion, one may produce a startling, though possibly a meretricious, effect. Now, it was not really difficult, by an inspection of the groove between your left forefinger and thumb, to feel sure that you did NOT propose to invest your small capital in the gold fields." "I see no connection." "Very likely not; but I can quickly show you a close connection. Here are the missing links of the very simple chain: 1. You had chalk between your left finger and thumb when you returned from the club last night. 2. You put chalk there when you play billiards, to steady the cue. 3. You never play billiards except with Thurston. 4. You told me, four weeks ago, that Thurston had an option on some South African property which would expire in a month, and which he desired you to share with him. 5. Your cheque book is locked in my drawer, and you have not asked for the key. 6. You do not propose to invest your money in this manner." "How absurdly simple!" I cried. > CoincidenceIndex(dancemen); 0.0617615029004579993435240488001 > S:=SubstitutionCryptosystem(); > dm:=Encoding(S,dancemen); > rk:=RandomKey(S); > rk; VTPWOZQURAFEJYDXCISGBLNHKM > cdm:=Enciphering(rk,dm); > CoincidenceIndex(cdm); 0.0617615029004579993435240488001 > /* > Exactly the same as for the unenciphered text. > */ > rk:=RandomKey(S); > rk; LOTEBCSHGMRAZXYNJUWKQVDFPI > cdm:=Enciphering(rk,dm); > CoincidenceIndex(cdm); 0.0617615029004579993435240488001 > /* > Still the same > */ > rk:=RandomKey(S); > rk; WCAQLRTPFJDNKVYBGOUEZMXHSI > cdm:=Enciphering(rk,dm); > CoincidenceIndex(cdm); 0.0617615029004579993435240488001 > /* > Clearly enciphering with a simple substitution cipher does not > change the coincidence index. This is because, for all i and j, > the i-th and j-th letters of the ciphertext are equal if and > only if the i-th and j-th letters of the plaintext are equal. > So the probability that two randomly chosen letters are equal > is the same for the ciphertext as for the plaintext. > > This, of course, is the weakness of simple substitution ciphers: > they keep the same uneven distribution of the letters (just > shuffled up), allowing one to guess the key by investigating > letter frequencies. Vigenere ciphers, especially if the keyword > is long, have the effect of "evening up" the frequencies of > the letters -- decreasing the coincidence index -- and thus > (so it was hoped!) making frequency analysis more difficult. > When first introduced, in Napoleonic times, Vigenere ciphers > were considered uncrackable. > */ > dmv:=Encoding(V,dancemen); > cdmv:=Enciphering(k,dmv); > CoincidenceIndex(cdmv); 0.0424911728525720666415119806861 > k:=RandomKey(V); > cdmv:=Enciphering(k,dmv); > CoincidenceIndex(cdmv); 0.0405880061230186850234521432099 > k:=RandomKey(V); > cdmv:=Enciphering(k,dmv); > CoincidenceIndex(cdmv); 0.0405554890899218670912286837044 > k:=RandomKey(V); > cdmv:=Enciphering(k,dmv); > CoincidenceIndex(cdmv); 0.0414684201323381894147854335962 > /* > The coincidence index is always less than one would get from > standard English, and it depends on the key. The common letters > in the plaintext (E's, T's, A's and suchlike) are not always > enciphered in the same way as they are when a simple substitution > cipher is used. An E that occurs as the 7th letter of the plaintext > will be enciphered differently from an E that occurs as the 8th > letter. The end result is that you get a more even distribution > of the letters. But it is still a bit uneven. > */ > 1/26.0; 0.0384615384615384615384615384615 > VV:=VigenereCryptosystem(20); > kk:=RandomKey(VV); > dmvv:=Encoding(VV,dancemen); > cdmvv:=Enciphering(kk,dmvv); > CoincidenceIndex(cdmvv); 0.0408174659414754757149912725510 > kk:=RandomKey(VV); > cdmvv:=Enciphering(kk,dmvv); > CoincidenceIndex(cdmvv); 0.0398775396262995309571358015602 > kk:=RandomKey(VV); > cdmvv:=Enciphering(kk,dmvv); > CoincidenceIndex(cdmvv); 0.0391437590303788847884705644159 > /* > We are getting smaller numbers than we had before. > In the extreme case, if we had a keyword as long as the text, > then every letter would be enciphered by a different rule, > and the ciphertext would be just as random as the key. > It is impossible to crack a Vigenere cipher that is used > once only and on a text that is shorter than the key. > For such a ciphertext you just have to get hold of the key > -- there is absolutely no alternative. > */ > VV:=VigenereCryptosystem(1000); > kk:=RandomKey(VV); > dmvv:=Encoding(VV,dancemen); > cdmvv:=Enciphering(kk,dmvv); > CoincidenceIndex(cdmvv); 0.0386682741124537169116180905139 > 1/26.0; 0.0384615384615384615384615384615 > kk:=RandomKey(VV); > cdmvv:=Enciphering(kk,dmvv); > CoincidenceIndex(cdmvv); 0.0384694907403146789863275078762 > alph:="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; > Decimation(alph,1,3); ADGJMPSV > /* > Start with the 1st letter of alph and then take every 3rd letter. > */ > Decimation(alph,2,3); BEHKNQTW > /* > Now we start at the second letter and take every 3rd letter after that. > */ > Decimation(alph,2,6); BHNT > /* > Every 6th letter, starting at the 2nd. > */ > Type(dm); CryptTxt > Type(alph); MonStgElt > /* > MonStgElt is just magma's name for a string. magma calls it > a MonStgElt, we call it a string. > */ > Type(k); CryptKey > Type(Sk); MonStgElt > k; UJDNTAC > Sk; CARSLAW > Type(m); CryptKey > Type(Sm); MonStgElt > m; YAJIPAE > Sm; YAJIPAE > /* > They look the same, but in magma's eyes they are different. > */ > scdmv:=String(cdmv); > Type(vt1); MonStgElt > Type(vt2); MonStgElt > Type(vt3); MonStgElt > Type(vt4); MonStgElt > CoincidenceIndex(Decimation(scdmv,1,7)); 0.0583054323892257110970349591289 > CoincidenceIndex(Decimation(scdmv,2,7)); 0.0567369468826350556510723011492 > CoincidenceIndex(Decimation(scdmv,3,7)); 0.0767049739088468615208276777365 > /* > All these values are rather high, similar to what you might > get from normal English. > */ > CoincidenceIndex(Decimation(scdmv,1,6)); 0.0427242524916943521594684385382 > CoincidenceIndex(Decimation(scdmv,2,6)); 0.0410852713178294573643410852713 > CoincidenceIndex(Decimation(scdmv,3,6)); 0.0398006644518272425249169435216 > CoincidenceIndex(Decimation(scdmv,1,9)); 0.0391457286432160804020100502513 > CoincidenceIndex(Decimation(scdmv,2,9)); 0.0425628140703517587939698492462 > CoincidenceIndex(Decimation(scdmv,3,9)); 0.0405025125628140703517587939698 > CoincidenceIndex(Decimation(scdmv,4,5)); 0.0406586642043705755617112957833 > CoincidenceIndex(Decimation(scdmv,1,4)); 0.0411234294161123429416112342942 > CoincidenceIndex(Decimation(scdmv,1,10)); 0.0424581005586592178770949720670 > /* > For ciphertext produced by a Vigenere cipher, the > coincidence index is high for decimations with period > equal to the length of the keyword and low for decimations > of a different period. > */ > for i:=2 to 20 do for> print "Period:",i,"CI:",CoincidenceIndex(Decimation(vt1,1,i)); for> end for; Period: 2 CI: 0.0409995044897075380750330432572 Period: 3 CI: 0.0402920072377862357272103325638 Period: 4 CI: 0.0411008978796897453466981795256 Period: 5 CI: 0.0406125212680995867912080280565 Period: 6 CI: 0.0406835042093856797532716512461 Period: 7 CI: 0.0408375583783096185647567646150 Period: 8 CI: 0.0416938690723485073298118582705 Period: 9 CI: 0.0395018967507834405409863104074 Period: 10 CI: 0.0416666666666666666666666666667 Period: 11 CI: 0.0413879645502111973827210289850 Period: 12 CI: 0.0423344178013415270916174639515 Period: 13 CI: 0.0579159037916842714739527095754 Period: 14 CI: 0.0415134859680413496887853528919 Period: 15 CI: 0.0414657062323833385530848731600 Period: 16 CI: 0.0435986159169550173010380622838 Period: 17 CI: 0.0398620986856280973928032751562 Period: 18 CI: 0.0388803426537568244201128103037 Period: 19 CI: 0.0408824124671119206638332321393 Period: 20 CI: 0.0429914912673533363188535602329 > /* > The CI is low except when we take a decimation of period 13. > So it looks like 13 is the length of the keyword that was used. > */ > SortedFreqDist(Decimation(vt1,1,13)); [ <0.0949720665812492370605468750000, F>, <0.0893854750320315361022949218750, P>, <0.0893854750320315361022949218750, T>, <0.0810055863112211227416992187500, J>, <0.0782122900709509849548339843750, B>, <0.0586592177860438823699951171875, O>, <0.0586592177860438823699951171875, S>, <0.0558659220114350318908691406250, I>, <0.0530726257711648941040039062500, U>, <0.0446927375160157680511474609375, M>, <0.0418994412757456302642822265625, E>, <0.0335195530205965042114257812500, N>, <0.0335195530205965042114257812500, Q>, <0.0307262570131570100784301757812, D>, <0.0307262570131570100784301757812, V>, <0.0251396647654473781585693359375, G>, <0.0223463687580078840255737304688, H>, <0.0167597765102982521057128906250, C>, <0.0167597765102982521057128906250, Z>, <0.0139664805028587579727172851562, W>, <0.0111731843790039420127868652344, L>, <0.0111731843790039420127868652344, X>, <0.00279329609475098550319671630859, K>, <0.00279329609475098550319671630859, R>, <0.00279329609475098550319671630859, Y>, <0.000000000000000000000000000000, A> ] > /* > Assuming a keyword of length 13, the same translation cipher is applied > to every 13th letter. So Decimation(vt1,1,13) is the same as > Decimation(plainttext,1,13) would be, except alphabetically shifted. > We would expect E to be the most frequent letter in the plaintext. > In Decimation(vt1,1,13) the most frequent letter was F. So the alphabetical > shift that was applied was probably a shift of one place alphabetically. > That means that the key for this translation cipher is B (the thing > that represents A). > So B is the first letter of the keyword. > > Now we do the same with Decimation(vt1,2,13) to get the 2nd letter of the > keyword. > */ > SortedFreqDist(Decimation(vt1,2,13)); [ <0.125698324292898178100585937500, E>, <0.0949720665812492370605468750000, A>, <0.0837988825514912605285644531250, O>, <0.0810055863112211227416992187500, T>, <0.0754189947620034217834472656250, I>, <0.0698324022814631462097167968750, R>, <0.0642458098009228706359863281250, S>, <0.0530726257711648941040039062500, H>, <0.0474860332906246185302734375000, N>, <0.0363128492608666419982910156250, U>, <0.0335195530205965042114257812500, F>, <0.0335195530205965042114257812500, L>, <0.0307262570131570100784301757812, D>, <0.0307262570131570100784301757812, Y>, <0.0279329610057175159454345703125, M>, <0.0251396647654473781585693359375, C>, <0.0223463687580078840255737304688, W>, <0.0195530725177377462387084960938, V>, <0.0167597765102982521057128906250, G>, <0.0111731843790039420127868652344, P>, <0.00558659218950197100639343261719, B>, <0.00558659218950197100639343261719, K>, <0.00279329609475098550319671630859, J>, <0.00279329609475098550319671630859, X>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, Z> ] > /* > An alphabetic shift of 0 steps takes E to E. The key for such a translation > cipher is A. > The second letter of the keyword is probably A. > */ > SortedFreqDist(Decimation(vt1,3,13)); [ <0.136871509253978729248046875000, X>, <0.0949720665812492370605468750000, G>, <0.0893854750320315361022949218750, H>, <0.0726256985217332839965820312500, L>, <0.0698324022814631462097167968750, B>, <0.0642458098009228706359863281250, T>, <0.0614525140263140201568603515625, M>, <0.0586592177860438823699951171875, K>, <0.0558659220114350318908691406250, A>, <0.0474860332906246185302734375000, P>, <0.0363128492608666419982910156250, E>, <0.0279329610057175159454345703125, V>, <0.0279329610057175159454345703125, W>, <0.0279329610057175159454345703125, Y>, <0.0223463687580078840255737304688, F>, <0.0223463687580078840255737304688, R>, <0.0167597765102982521057128906250, N>, <0.0167597765102982521057128906250, U>, <0.0139664805028587579727172851562, O>, <0.0111731843790039420127868652344, D>, <0.0111731843790039420127868652344, I>, <0.0111731843790039420127868652344, Z>, <0.00279329609475098550319671630859, C>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, S> ] > Index(alphabet,"X"); 24 > Index(alphabet,"E"); 5 > /* > So this is an alphabetic shift of 19 steps. > */ > alphabet[20]; T > /* > The third letter of the keyword is T > */ > SortedFreqDist(Decimation(vt1,4,13))[1]; <0.131284916773438453674316406250, Q> > Index(alphabet,"Q"); 17 > alphabet[13]; M > /* > M is the 4th letter of the keyword > */ > SortedFreqDist(Decimation(vt1,4,13))[1,2]; Q > SortedFreqDist(Decimation(vt1,5,13))[1,2]; E > /* > This corresponds to a zero alphabetic shift. The 5th letter > of the keyword is A. > */ > SortedFreqDist(Decimation(vt1,6,13))[1,2]; R > Index(alphabet,SortedFreqDist(Decimation(vt1,6,13))[1,2]); 18 > alphabet[Index(alphabet,SortedFreqDist(Decimation(vt1,6,13))[1,2])-4]; N > /* > So far they keyword is BATMAN... > */ > alphabet[Index(alphabet,SortedFreqDist(Decimation(vt1,7,13))[1,2])-4]; F > /* > BATMANF... > > Actually I've been lucky so far that the command I've used > has not come out as alphabet[-2], or something like that. I need > to make sure that I only use alphabet[i] for i in [1..26]. > */ > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,7,13))[1,2])-5) mod 26)+1]; F > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,8,13))[1,2])-5) mod 26)+1]; O > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,9,13))[1,2])-5) mod 26)+1]; R > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,10,13))[1,2])-5) mod 26)+1]; E > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,11,13))[1,2])-5) mod 26)+1]; V > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,12,13))[1,2])-5) mod 26)+1]; E > alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,13,13))[1,2])-5) mod 26)+1]; R > &*[alphabet[((Index(alphabet,SortedFreqDist(Decimation(vt1,i,13))[1,2])-5) mod 26)+1]:\ i in [1..13]]; BATMANFOREVER > V1:=VigenereCryptosystem(13); > k1:=V1!"BATMANFOREVER"; > Enciphering(InverseKey(k1),Encoding(V1,vt1)); TOSHERLOCKHOLMESSHEISALWAYSTHEWOMANIHAVESELDOMHEARDHIMMENTIONHERUNDERANYOTHERNAMEINHISEYE\ SSHEECLIPSESANDPREDOMINATESTHEWHOLEOFHERSEXITWASNOTTHATHEFELTANYEMOTIONAKINTOLOVEFORIRENE\ ADLERALLEMOTIONSANDTHATONEPARTICULARLYWEREABHORRENTTOHISCOLDPRECISEBUTADMIRABLYBALANCEDMI\ NDHEWASITAKEITTHEMOSTPERFECTREASONINGANDOBSERVINGMACHINETHATTHEWORLDHASSEENBUTASALOVERHEW\ OULDHAVEPLACEDHIMSELFINAFALSEPOSITIONHENEVERSPOKEOFTHESOFTERPASSIONSSAVEWITHAGIBEANDASNEE\ RTHEYWEREADMIRABLETHINGSFORTHEOBSERVEREXCELLENTFORDRAWINGTHEVEILFROMMENSMOTIVESANDACTIONS\ BUTFORTHETRAINEDTEASONERTOADMITSUCHINTRUSIONSINTOHISOWNDELICATEANDFINELYADJUSTEDTEMPERAME\ NTWASTOINTRODUCEADISTRACTINGFACTORWHICHMIGHTTHROWADOUBTUPONALLHISMENTALRESULTSGRITINASENS\ ITIVEINSTRUMENTORACRACKINONEOFHISOWNHIGHPOWERLENSESWOULDNOTBEMOREDISTURBINGTHANASTRONGEMO\ TIONINANATURESUCHASHISANDYETTHEREWASBUTONEWOMANTOHIMANDTHATWOMANWASTHELATEIRENEADLEROFDUB\ IOUSANDQUESTIONABLEMEMORYIHADSEENLITTLEOFHOLMESLATELYMYMARRIAGEHADDRIFTEDUSAWAYFROMEACHOT\ HERMYOWNCOMPLETEHAPPINESSANDTHEHOMECENTREDINTERESTSWHICHRISEUPAROUNDTHEMANWHOFIRSTFINDSHI\ MSELFMASTEROFHISOWNESTABLISHMENTWERESUFFICIENTTOABSORBALLMYATTENTIONWHILEHOLMESWHOLOATHED\ EVERYFORMOFSOCIETYWITHHISWHOLEBOHEMIANSOULREMAINEDINOURLODGINGSINBAKERSTREETBURIEDAMONGHI\ SOLDBOOKSANDALTERNATINGFROMWEEKTOWEEKBETWEENCOCAINEANDAMBITIONTHEDROWSINESSOFTHEDRUGANDTH\ EFIERCEENERGYOFHISOWNKEENNATUREHEWASSTILLASEVERDEEPLYATTRACTEDBYTHESTUDYOFCRIMEANDOCCUPIE\ DHISIMMENSEFACULTIESANDEXTRAORDINARYPOWERSOFOBSERVATIONINFOLLOWINGOUTTHOSECLUESANDCLEARIN\ GUPTHOSEMYSTERIESWHICHHADBEENABANDONEDASHOPELESSBYTHEOFFICIALPOLICEFROMTIMETOTIMEIHEARDSO\ MEVAGUEACCOUNTOFHISDOINGSOFHISSUMMONSTOODESSAINTHECASEOFTHETREPOFFMURDEROFHISCLEARINGUPOF\ THESINGULARTRAGEDYOFTHEATKINSONBROTHERSATTRINCOMALEEANDFINALLYOFTHEMISSIONWHICHHEHADACCOM\ PLISHEDSODELICATELYANDSUCCESSFULLYFORTHEREIGNINGFAMILYOFHOLLANDBEYONDTHESESIGNSOFHISACTIV\ ITYHOWEVERWHICHIMERELYSHAREDWITHALLTHEREADERSOFTHEDAILYPRESSIKNEWLITTLEOFMYFORMERFRIENDAN\ DCOMPANIONONENIGHTITWASONTHETWENTIETHOFMARCHIWASRETURNINGFROMAJOURNEYTOAPATIENTFORIHADNOW\ RETURNEDTOCIVILPRACTICEWHENMYWAYLEDMETHROUGHBAKERSTREETASIPASSEDTHEWELLREMEMBEREDDOORWHIC\ HMUSTALWAYSBEASSOCIATEDINMYMINDWITHMYWOOINGANDWITHTHEDARKINCIDENTSOFTHESTUDYINSCARLETIWAS\ SEIZEDWITHAKEENDESIRETOSEEHOLMESAGAINANDTOKNOWHOWHEWASEMPLOYINGHISEXTRAORDINARYPOWERSHISR\ OOMSWEREBRILLIANTLYLITANDEVENASILOOKEDUPISAWHISTALLSPAREFIGUREPASSTWICEINADARKSILHOUETTEA\ GAINSTTHEBLINDHEWASPACINGTHEROOMSWIFTLYEAGERLYWITHHISHEADSUNKUPONHISCHESTANDHISHANDSCLASP\ EDBEHINDHIMTOMEWHOKNEWHISEVERYMOODANDHABITHISATTITUDEANDMANNERTOLDTHEIROWNSTORYHEWASATWOR\ KAGAINHEHADRISENOUTOFHISDRUGCREATEDDREAMSANDWASHOTUPONTHESCENTOFSOMENEWPROBLEMIRANGTHEBEL\ LANDWASSHOWNUPTOTHECHAMBERWHICHHADFORMERLYBEENINPARTMYOWNHISMANNERWASNOTEFFUSIVEITSELDOMW\ ASBUTHEWASGLADITHINKTOSEEMEWITHHARDLYAWORDSPOKENBUTWITHAKINDLYEYEHEWAVEDMETOANARMCHAIRTHR\ EWACROSSHISCASEOFCIGARSANDINDICATEDASPIRITCASEANDAGASOGENEINTHECORNERTHENHESTOODBEFORETHE\ FIREANDLOOKEDMEOVERINHISSINGULARINTROSPECTIVEFASHIONWEDLOCKSUITSYOUHEREMARKEDITHINKWATSON\ THATYOUHAVEPUTONSEVENANDAHALFPOUNDSSINCEISAWYOUSEVENIANSWEREDINDEEDISHOULDHAVETHOUGHTALIT\ TLEMOREJUSTATRIFLEMOREIFANCYWATSONANDINPRACTICEAGAINIOBSERVEYOUDIDNOTTELLMETHATYOUINTENDE\ DTOGOINTOHARNESSTHENHOWDOYOUKNOWISEEITIDEDUCEITHOWDOIKNOWTHATYOUHAVEBEENGETTINGYOURSELFVE\ RYWETLATELYANDTHATYOUHAVEAMOSTCLUMSYANDCARELESSSERVANTGIRLMYDEARHOLMESSAIDITHISISTOOMUCHY\ OUWOULDCERTAINLYHAVEBEENBURNEDHADYOULIVEDAFEWCENTURIESAGOITISTRUETHATIHADACOUNTRYWALKONTH\ URSDAYANDCAMEHOMEINADREADFULMESSBUTASIHAVECHANGEDMYCLOTHESICANTIMAGINEHOWYOUDEDUCEITASTOM\ ARYJANESHEISINCORRIGIBLEANDMYWIFEHASGIVENHERNOTICEBUTTHEREAGAINIFAILTOSEEHOWYOUWORKITOUTH\ ECHUCKLEDTOHIMSELFANDRUBBEDHISLONGNERVOUSHANDSTOGETHERITISSIMPLICITYITSELFSAIDHEMYEYESTEL\ LMETHATONTHEINSIDEOFYOURLEFTSHOEJUSTWHERETHEFIRELIGHTSTRIKESITTHELEATHERISSCOREDBYSIXALMO\ STPARALLELCUTSOBVIOUSLYTHEYHAVEBEENCAUSEDBYSOMEONEWHOHASVERYCARELESSLYSCRAPEDROUNDTHEEDGE\ SOFTHESOLEINORDERTOREMOVECRUSTEDMUDFROMITHENCEYOUSEEMYDOUBLEDEDUCTIONTHATYOUHADBEENOUTINV\ ILEWEATHERANDTHATYOUHADAPARTICULARLYMALIGNANTBOOTSLITTINGSPECIMENOFTHELONDONSLAVEYASTOYOU\ RPRACTICEIFAGENTLEMANWALKSINTOMYROOMSSMELLINGOFIODOFORMWITHABLACKMARKOFNITRATEOFSILVERUPO\ NHISRIGHTFOREFINGERANDABULGEONTHERIGHTSIDEOFHISTOPHATTOSHOWWHEREHEHASSECRETEDHISSTETHOSCO\ PEIMUSTBEDULLINDEEDIFIDONOTPRONOUNCEHIMTOBEANACTIVEMEMBEROFTHEMEDICALPROFESSIONICOULDNOTH\ ELPLAUGHINGATTHEEASEWITHWHICHHEEXPLAINEDHISPROCESSOFDEDUCTIONWHENIHEARYOUGIVEYOURREASONSI\ REMARKEDTHETHINGALWAYSAPPEARSTOMETOBESORIDICULOUSLYSIMPLETHATICOULDEASILYDOITMYSELFTHOUGH\ ATEACHSUCCESSIVEINSTANCEOFYOURREASONINGIAMBAFFLEDUNTILYOUEXPLAINYOURPROCESSANDYETIBELIEVE\ THATMYEYESAREASGOODASYOURS > /* > "A Scandal in Bohemia", by Conan-Doyle > */ > /* Let us try the same method on vt2 */ > for i:=2 to 25 do for> print "Period:",i,"CI:",CoincidenceIndex(Decimation(vt2,1,i)); for> end for; Period: 2 CI: 0.0444364912450018832997556401812 Period: 3 CI: 0.0402948402948402948402948402949 Period: 4 CI: 0.0452469748598105765876955273537 Period: 5 CI: 0.0524070535385027992892822421134 Period: 6 CI: 0.0421079386596627975938320765907 Period: 7 CI: 0.0425517900075750090570760465040 Period: 8 CI: 0.0457937877480586712683347713546 Period: 9 CI: 0.0395790624572912395790624572912 Period: 10 CI: 0.0605477973419685623692909667409 Period: 11 CI: 0.0411723941135705841588194529371 Period: 12 CI: 0.0431156416134224259864410086329 Period: 13 CI: 0.0415860735009671179883945841393 Period: 14 CI: 0.0416583615706597568267889176799 Period: 15 CI: 0.0529425130652124517155192001818 Period: 16 CI: 0.0451376786336702683861972812827 Period: 17 CI: 0.0424505072392396336058307889294 Period: 18 CI: 0.0402432283029297954671088999447 Period: 19 CI: 0.0398622047244094488188976377953 Period: 20 CI: 0.0681479474325972090502641918439 Period: 21 CI: 0.0418290854572713643178410794603 Period: 22 CI: 0.0386568386568386568386568386568 Period: 23 CI: 0.0380952380952380952380952380953 Period: 24 CI: 0.0425742574257425742574257425743 Period: 25 CI: 0.0539089347079037800687285223368 > /* For period 10 the CI is over 0.06; so the length of > the key is probably 10. Note that 20 also gives a high > CI: it is always true that multiples of the keyword length > give high values for the CI. It is best to assume that > the smallest number that gives a CI near 0.06 is the > keyword length. */ > SortedFreqDist(Decimation(vt2,1,10)); [ <0.106557376682758331298828125000, K>, <0.102459016256034374237060546875, Z>, <0.0983606558293104171752929687500, U>, <0.0655737705528736114501953125000, G>, <0.0655737705528736114501953125000, T>, <0.0573770492337644100189208984375, O>, <0.0573770492337644100189208984375, X>, <0.0532786883413791656494140625000, R>, <0.0532786883413791656494140625000, Y>, <0.0491803279146552085876464843750, A>, <0.0491803279146552085876464843750, N>, <0.0491803279146552085876464843750, S>, <0.0409836065955460071563720703125, J>, <0.0286885246168822050094604492188, H>, <0.0286885246168822050094604492188, I>, <0.0204918032977730035781860351562, V>, <0.0163934426382184028625488281250, C>, <0.0163934426382184028625488281250, L>, <0.0122950819786638021469116210938, B>, <0.0122950819786638021469116210938, E>, <0.0122950819786638021469116210938, M>, <0.00409836065955460071563720703125, P>, <0.000000000000000000000000000000, D>, <0.000000000000000000000000000000, F>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, W> ] > /* Assuming that the most frequent letter represents E then the one that > represents A is four places earlier than the most frequent letter */ > alphabet[Index(alphabet,"K")-4]; G > /* It looks like G is the first letter of the key */ > SortedFreqDist(Decimation(vt2,2,10)); [ <0.118852458894252777099609375000, S>, <0.0942622954025864601135253906250, C>, <0.0942622954025864601135253906250, H>, <0.0737704914063215255737304687500, O>, <0.0696721309795975685119628906250, F>, <0.0655737705528736114501953125000, B>, <0.0614754096604883670806884765625, W>, <0.0573770492337644100189208984375, R>, <0.0491803279146552085876464843750, A>, <0.0450819670222699642181396484375, V>, <0.0450819670222699642181396484375, Z>, <0.0409836065955460071563720703125, G>, <0.0368852457031607627868652343750, Q>, <0.0286885246168822050094604492188, M>, <0.0245901639573276042938232421875, T>, <0.0204918032977730035781860351562, K>, <0.0163934426382184028625488281250, D>, <0.0163934426382184028625488281250, I>, <0.0163934426382184028625488281250, P>, <0.0122950819786638021469116210938, J>, <0.00819672131910920143127441406250, U>, <0.00409836065955460071563720703125, Y>, <0.000000000000000000000000000000, E>, <0.000000000000000000000000000000, L>, <0.000000000000000000000000000000, N>, <0.000000000000000000000000000000, X> ] > alphabet[Index(alphabet,"S")-4]; O > /* Probably the 2nd letter of the key */ > SortedFreqDist(Decimation(vt2,3,10)); [ <0.122950819320976734161376953125, X>, <0.0901639340445399284362792968750, T>, <0.0860655736178159713745117187500, M>, <0.0696721309795975685119628906250, H>, <0.0655737705528736114501953125000, A>, <0.0614754096604883670806884765625, B>, <0.0614754096604883670806884765625, L>, <0.0532786883413791656494140625000, G>, <0.0532786883413791656494140625000, K>, <0.0491803279146552085876464843750, F>, <0.0491803279146552085876464843750, R>, <0.0368852457031607627868652343750, Z>, <0.0327868852764368057250976562500, N>, <0.0327868852764368057250976562500, V>, <0.0327868852764368057250976562500, W>, <0.0286885246168822050094604492188, E>, <0.0204918032977730035781860351562, P>, <0.0163934426382184028625488281250, Y>, <0.0122950819786638021469116210938, U>, <0.00819672131910920143127441406250, D>, <0.00819672131910920143127441406250, I>, <0.00819672131910920143127441406250, O>, <0.000000000000000000000000000000, C>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, S> ] > alphabet[Index(alphabet,"X")-4]; T > SortedFreqDist(Decimation(vt2,4,10)); [ <0.106557376682758331298828125000, P>, <0.0860655736178159713745117187500, L>, <0.0819672131910920143127441406250, Y>, <0.0778688527643680572509765625000, O>, <0.0737704914063215255737304687500, V>, <0.0696721309795975685119628906250, A>, <0.0696721309795975685119628906250, U>, <0.0614754096604883670806884765625, H>, <0.0532786883413791656494140625000, Z>, <0.0491803279146552085876464843750, T>, <0.0450819670222699642181396484375, F>, <0.0327868852764368057250976562500, J>, <0.0327868852764368057250976562500, S>, <0.0286885246168822050094604492188, K>, <0.0245901639573276042938232421875, B>, <0.0245901639573276042938232421875, D>, <0.0245901639573276042938232421875, W>, <0.0163934426382184028625488281250, I>, <0.0122950819786638021469116210938, C>, <0.0122950819786638021469116210938, M>, <0.00819672131910920143127441406250, N>, <0.00409836065955460071563720703125, Q>, <0.00409836065955460071563720703125, R>, <0.000000000000000000000000000000, E>, <0.000000000000000000000000000000, G>, <0.000000000000000000000000000000, X> ] > alphabet[Index(alphabet,"P")-4]; L > /* So far the probable key is GOTL... */ > SortedFreqDist(Decimation(vt2,5,10)); [ <0.143442623317241668701171875000, E>, <0.102459016256034374237060546875, T>, <0.0778688527643680572509765625000, I>, <0.0778688527643680572509765625000, R>, <0.0696721309795975685119628906250, O>, <0.0532786883413791656494140625000, A>, <0.0532786883413791656494140625000, L>, <0.0532786883413791656494140625000, N>, <0.0491803279146552085876464843750, H>, <0.0450819670222699642181396484375, C>, <0.0409836065955460071563720703125, S>, <0.0327868852764368057250976562500, M>, <0.0327868852764368057250976562500, U>, <0.0327868852764368057250976562500, Y>, <0.0286885246168822050094604492188, F>, <0.0204918032977730035781860351562, D>, <0.0163934426382184028625488281250, G>, <0.0163934426382184028625488281250, P>, <0.0163934426382184028625488281250, V>, <0.00819672131910920143127441406250, B>, <0.00819672131910920143127441406250, K>, <0.00819672131910920143127441406250, W>, <0.00819672131910920143127441406250, X>, <0.00409836065955460071563720703125, Z>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, Q> ] > /* E is represented by E; so A is represented by A */ > /* GOTLA... */ > SortedFreqDist(Decimation(vt2,6,10)); [ <0.131147541105747222900390625000, Q>, <0.0860655736178159713745117187500, A>, <0.0860655736178159713745117187500, M>, <0.0819672131910920143127441406250, E>, <0.0819672131910920143127441406250, U>, <0.0819672131910920143127441406250, Z>, <0.0778688527643680572509765625000, T>, <0.0614754096604883670806884765625, F>, <0.0491803279146552085876464843750, D>, <0.0368852457031607627868652343750, Y>, <0.0327868852764368057250976562500, G>, <0.0327868852764368057250976562500, X>, <0.0286885246168822050094604492188, P>, <0.0286885246168822050094604492188, R>, <0.0245901639573276042938232421875, O>, <0.0204918032977730035781860351562, I>, <0.0163934426382184028625488281250, N>, <0.0163934426382184028625488281250, S>, <0.0122950819786638021469116210938, K>, <0.00409836065955460071563720703125, B>, <0.00409836065955460071563720703125, C>, <0.00409836065955460071563720703125, H>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, L>, <0.000000000000000000000000000000, V>, <0.000000000000000000000000000000, W> ] > alphabet[Index(alphabet,"Q")-4]; M > /* GOTLAM... */ > SortedFreqDist(Decimation(vt2,7,10)); [ <0.155737705528736114501953125000, G>, <0.106557376682758331298828125000, V>, <0.0778688527643680572509765625000, Q>, <0.0737704914063215255737304687500, C>, <0.0696721309795975685119628906250, P>, <0.0655737705528736114501953125000, U>, <0.0491803279146552085876464843750, J>, <0.0491803279146552085876464843750, K>, <0.0491803279146552085876464843750, O>, <0.0450819670222699642181396484375, W>, <0.0409836065955460071563720703125, F>, <0.0368852457031607627868652343750, H>, <0.0368852457031607627868652343750, T>, <0.0245901639573276042938232421875, D>, <0.0245901639573276042938232421875, I>, <0.0204918032977730035781860351562, E>, <0.0204918032977730035781860351562, Y>, <0.0163934426382184028625488281250, N>, <0.0122950819786638021469116210938, A>, <0.0122950819786638021469116210938, X>, <0.00409836065955460071563720703125, M>, <0.00409836065955460071563720703125, R>, <0.00409836065955460071563720703125, S>, <0.000000000000000000000000000000, B>, <0.000000000000000000000000000000, L>, <0.000000000000000000000000000000, Z> ] > alphabet[Index(alphabet,"G")-4]; C > /* GOTLAMC... */ > SortedFreqDist(Decimation(vt2,8,10)); [ <0.110655738040804862976074218750, M>, <0.106557376682758331298828125000, I>, <0.102459016256034374237060546875, A>, <0.0819672131910920143127441406250, Q>, <0.0778688527643680572509765625000, B>, <0.0696721309795975685119628906250, Z>, <0.0655737705528736114501953125000, V>, <0.0655737705528736114501953125000, W>, <0.0532786883413791656494140625000, P>, <0.0368852457031607627868652343750, G>, <0.0368852457031607627868652343750, U>, <0.0245901639573276042938232421875, E>, <0.0245901639573276042938232421875, T>, <0.0204918032977730035781860351562, C>, <0.0204918032977730035781860351562, N>, <0.0204918032977730035781860351562, O>, <0.0163934426382184028625488281250, J>, <0.0163934426382184028625488281250, X>, <0.0122950819786638021469116210938, K>, <0.0122950819786638021469116210938, L>, <0.0122950819786638021469116210938, S>, <0.00819672131910920143127441406250, F>, <0.00409836065955460071563720703125, D>, <0.000000000000000000000000000000, H>, <0.000000000000000000000000000000, R>, <0.000000000000000000000000000000, Y> ] > alphabet[Index(alphabet,"M")-4]; I > /* GOTLAMCI.. */ > SortedFreqDist(Decimation(vt2,9,10)); [ <0.122950819320976734161376953125, H>, <0.118852458894252777099609375000, X>, <0.0819672131910920143127441406250, M>, <0.0737704914063215255737304687500, K>, <0.0696721309795975685119628906250, L>, <0.0655737705528736114501953125000, B>, <0.0655737705528736114501953125000, T>, <0.0532786883413791656494140625000, G>, <0.0491803279146552085876464843750, W>, <0.0409836065955460071563720703125, A>, <0.0409836065955460071563720703125, N>, <0.0327868852764368057250976562500, E>, <0.0327868852764368057250976562500, R>, <0.0327868852764368057250976562500, Y>, <0.0245901639573276042938232421875, F>, <0.0245901639573276042938232421875, V>, <0.0204918032977730035781860351562, O>, <0.0163934426382184028625488281250, U>, <0.0122950819786638021469116210938, P>, <0.00819672131910920143127441406250, I>, <0.00819672131910920143127441406250, Z>, <0.00409836065955460071563720703125, C>, <0.000000000000000000000000000000, D>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, S> ] > alphabet[Index(alphabet,"H")-4]; D > /* GOTLAMCID. */ > SortedFreqDist(Decimation(vt2,10,10)); [ <0.118852458894252777099609375000, C>, <0.0942622954025864601135253906250, R>, <0.0819672131910920143127441406250, M>, <0.0778688527643680572509765625000, Q>, <0.0778688527643680572509765625000, Y>, <0.0737704914063215255737304687500, L>, <0.0655737705528736114501953125000, J>, <0.0532786883413791656494140625000, G>, <0.0532786883413791656494140625000, P>, <0.0409836065955460071563720703125, F>, <0.0368852457031607627868652343750, B>, <0.0368852457031607627868652343750, S>, <0.0327868852764368057250976562500, K>, <0.0286885246168822050094604492188, U>, <0.0204918032977730035781860351562, N>, <0.0204918032977730035781860351562, T>, <0.0204918032977730035781860351562, W>, <0.0163934426382184028625488281250, D>, <0.0163934426382184028625488281250, Z>, <0.00819672131910920143127441406250, A>, <0.00819672131910920143127441406250, E>, <0.00819672131910920143127441406250, I>, <0.00409836065955460071563720703125, O>, <0.00409836065955460071563720703125, X>, <0.000000000000000000000000000000, H>, <0.000000000000000000000000000000, V> ] > alphabet[Index(alphabet,"C")-4]; >> alphabet[Index(alphabet,"C")-4]; ^ Runtime error in '[]': Sequence element -1 not defined > /* Of course, we need need to work modulo 26 here. The (-1)-th letter of > the alphabet means the 25th letter of the alphabet. */ > alphabet[Index(alphabet,"C")-4+26]; Y > /* GOTLAMCIDY */ > V2:=VigenereCryptosystem(10); > k2:=V2!"GOTLAMCIDY"; > dk2:=InverseKey(k2); > dk2; UMHPAOYSXC > Enciphering(dk2,Encoding(V2,vt2)); IHAZCALLUDUPOJMYFRYENDMNSHERBOCKHKLMESENEDAUINTHUAUTUINOFLQSTYEWRANDVOUNDDIMINTEEPCKNVERI\ ATIOJWITHQVERYOTOUTVLORIZFACETELDENLYGEDTLEMWNWITXFIERUREDHQIRWIPHANAFOLOGUFORMOINTRQSION\ YWASAXOUTTEWITHZRAWWXENHOHMESPKLLEDIEABRKPTLYENTOTXEROOIANDCBOSEDPHEDOERBEHENDMEOOUCOQLDN\ OJPOSSEBLYHQVECOIEATARETTENTIMECYDEANWATSENHESWIDCOHDIALHYIWAIAFRAEDTHAJYOUWAREENWAGEDOOI\ AMLERYMQCHSOJHENIYANWAYTINTDENEXJROOMJOTATQLLTHESGENJLEMAJMRWIBSONHWSBEEDMYPANTNERQNDHEHP\ ERIDMANYKFMYMESTSUYCESSVULCAOESANTIHAVANODOKBTTHWTHEWYLLBEKFTHEKTMOSPUSETEMEINUOURSQLSOTD\ ESTOKTGENPLEMADHALFNOSEFHOMHIOCHAIHANDGWVEABEBOFGNEETIDGWITDAQUISKLITPLEQUUSTIOJINGGBANCE\ BROMHYSSMAHLFATUNCIRYLEDEOESTRUTHESUTTEEOAIDHELMESNELAPIINGIJTOHIIARMCDAIRADDPUTPINGHYSFI\ NCERTIFSTOGATHERQSWASDISCUITOMWDENINZUDICEALMOEDSIKJOWMYTEARWWTSONJHATYKUSHAHEMYLKVEOFQLL\ THWTISBYZARRAANDOKTSIDATHECENVENPIONSQNDHUIDRUMHOUTIJEOFELERYDWYLIFUYOUHWVESHEWNYOQRRELYS\ HFONITBYJHEENPHUSIQSMWHECHHAIPROMLTEDYEUTOCDRONISLEANZIFYOKWILLAXCUSUMYSAUINGSESOMESHATTE\ EMBEHLISHIOMANUOFMYEWNLIPTLEATVENTQRESYEURCAOESHALEINDAEDBEUNOFTDEGREQTESTENTERUSTTOIEIOB\ IERVEZYOUWYLLREIEMBEHTHATEREMAHKEDTDEOTHURDAYFUSTBUFORESEWENJINTOPHEVEHYSIMLLEPREBLEMLRES\ EDTEDBUMISSCARYSQTHERBANDTDATFOHSTRAJGEEFVECTSWNDEXJRAORZINAROCOMBENATIENSWEIUSTGETOLIBEI\ TSULFWHECHISQLWAYOFARMEREDANINGTXANANUEFFOHTOFTDEIMAWINATEONAPHOPOSETIONMHICHETOOKJHELIXE\ RTYEFDOUXTINGOOUDIZDOCTERBUTJONETXELESOYOUMKSTCOIEROUDDTOMUVIEWVOROTDERWIIEISHWLLKEUPONPE\ LINGVACTULONFASTONYKUUNTYLYOUNREASENBREWKSDOMNUNDARTHECANDAYKNOWBEDGEOMETORERIGDTNOWCRJAB\ AZWILIONHENEHASREENGKODENEUGHTKCALLKPONMATHISCORNIJGANDJOBEGENANAHRATIREWHISHPROIISESJOBE\ OJEOFTXEMOSPSINGKLARWDICHIXAVELESTENUDTOFKRSOMUTIMEUOUHALEHEANDMERUMARKPHATTXESTRWNGESJAN\ DMKSTUNYQUETDINGSQREVENYOFTUNCONJECTETNOTWETHTHULARGARBUTMITHTDESMABLERCNIMESQNDOCYASIODA\ LLYENDEETWHERATHERUISROKMFORTOUBTSHETHURANYLOSITYVECREMEHAIBEENYOMMIJTEDAOFARAIIHAVAHEART\ ITISEMPOSIIBLEBORMEJOSAYSHETHURTHELRESEDTCASAISANYNSTAJCEOFSRIMEKRNOTRUTTHACOURIEOFERENTS\ YSCERPAINLOAMONCTHEMESTSIJGULAHTHATEHAVEUVERLESTENUDTOPARHAPIMRWIHSONYEUWOUHDHAVUTHEGNEAT\ KYNDNEOSTORUCOMMANCEYEURNANRATILEIASGYOUNETMERALYBESAUSEIYFRIUNDDRSATSODHASNKTHEAHDTHEKPE\ NIDGPARPBUTABSOBEYAUSEJHEPEYULIAHNATUNEOFTXESTONYMAKUSMEAJXIOUITOHAREEVEHYPOSOIBLETETAIHF\ ROMOOURLEPSASQRULESHENIXAVEHAARDSEMESLEGHTIDDICAPIONOVTHECKURSEEFEVEJTSIACABLEPOGUITEMYSA\ LFBYJHETHKUSANTSOFOPHERSYMILANCASEIWHICDOCCUHTOMYIEMOROINTHAPRESUNTINOTANCUIAMFKRCEDJOADM\ ETTHAJTHEFWCTSAHETOTDEBESJOFMYXELIEVUNIQQE > /* Well, it is not right. But I can see what it should be. > IHAZCALLUDUPOJMYFRYENDMNSHERBOCKHKLMES clearly should be > IHADCALLEDUPONMYFRIENDMRSHERLOCKHOLMES. The letters are wrong in the > 4th place, 9th place, 14th place, 19th place, ... . So I've got the > 4th and 9th letters of the key wrong. */ > SortedFreqDist(Decimation(vt2,4,10)); [ <0.106557376682758331298828125000, P>, <0.0860655736178159713745117187500, L>, <0.0819672131910920143127441406250, Y>, <0.0778688527643680572509765625000, O>, <0.0737704914063215255737304687500, V>, <0.0696721309795975685119628906250, A>, <0.0696721309795975685119628906250, U>, <0.0614754096604883670806884765625, H>, <0.0532786883413791656494140625000, Z>, <0.0491803279146552085876464843750, T>, <0.0450819670222699642181396484375, F>, <0.0327868852764368057250976562500, J>, <0.0327868852764368057250976562500, S>, <0.0286885246168822050094604492188, K>, <0.0245901639573276042938232421875, B>, <0.0245901639573276042938232421875, D>, <0.0245901639573276042938232421875, W>, <0.0163934426382184028625488281250, I>, <0.0122950819786638021469116210938, C>, <0.0122950819786638021469116210938, M>, <0.00819672131910920143127441406250, N>, <0.00409836065955460071563720703125, Q>, <0.00409836065955460071563720703125, R>, <0.000000000000000000000000000000, E>, <0.000000000000000000000000000000, G>, <0.000000000000000000000000000000, X> ] > /* I assumed that P represents E. If so then L represents A, which also looks > right since L is the second most frequent letter in this decimation. But it > also means that Y represents U, which looks a bit strange for the 3rd most > frequent letter, and O represents K, which is very strange for the 4th most > frequent letter. Maybe it is actually L that represents E. This would mean > that P represents I, meaning that I is the most frequent letter in this decimation. > I guess that is possible. And Y would represent R, O would represent H, > V would represent O, A would represent T, U would represent N, H would represent T. > This does all seem possible for the 8 most frequent letters. */ > alphabet[Index(alphabet,"L")-4]; H > /* try GOTHAMCIDY instead of GOTLAMCIDY. But the 9th letter is also wrong... */ > SortedFreqDist(Decimation(vt2,9,10)); [ <0.122950819320976734161376953125, H>, <0.118852458894252777099609375000, X>, <0.0819672131910920143127441406250, M>, <0.0737704914063215255737304687500, K>, <0.0696721309795975685119628906250, L>, <0.0655737705528736114501953125000, B>, <0.0655737705528736114501953125000, T>, <0.0532786883413791656494140625000, G>, <0.0491803279146552085876464843750, W>, <0.0409836065955460071563720703125, A>, <0.0409836065955460071563720703125, N>, <0.0327868852764368057250976562500, E>, <0.0327868852764368057250976562500, R>, <0.0327868852764368057250976562500, Y>, <0.0245901639573276042938232421875, F>, <0.0245901639573276042938232421875, V>, <0.0204918032977730035781860351562, O>, <0.0163934426382184028625488281250, U>, <0.0122950819786638021469116210938, P>, <0.00819672131910920143127441406250, I>, <0.00819672131910920143127441406250, Z>, <0.00409836065955460071563720703125, C>, <0.000000000000000000000000000000, D>, <0.000000000000000000000000000000, J>, <0.000000000000000000000000000000, Q>, <0.000000000000000000000000000000, S> ] > /* Maybe it is X that represents E */ > alphabet[Index(alphabet,"X")-4]; T > /* GOTHAMCITY */ > k2:=V2!"GOTHAMCITY"; > dk2:=InverseKey(k2); > Enciphering(dk2,Encoding(V2,vt2)); IHADCALLEDUPONMYFRIENDMRSHERLOCKHOLMESONEDAYINTHEAUTUMNOFLASTYEARANDFOUNDHIMINDEEPCONVERS\ ATIONWITHAVERYSTOUTFLORIDFACEDELDERLYGENTLEMANWITHFIERYREDHAIRWITHANAPOLOGYFORMYINTRUSION\ IWASABOUTTOWITHDRAWWHENHOLMESPULLEDMEABRUPTLYINTOTHEROOMANDCLOSEDTHEDOORBEHINDMEYOUCOULDN\ OTPOSSIBLYHAVECOMEATABETTERTIMEMYDEARWATSONHESAIDCORDIALLYIWASAFRAIDTHATYOUWEREENGAGEDSOI\ AMVERYMUCHSOTHENICANWAITINTHENEXTROOMNOTATALLTHISGENTLEMANMRWILSONHASBEENMYPARTNERANDHELP\ ERINMANYOFMYMOSTSUCCESSFULCASESANDIHAVENODOUBTTHATHEWILLBEOFTHEUTMOSTUSETOMEINYOURSALSOTH\ ESTOUTGENTLEMANHALFROSEFROMHISCHAIRANDGAVEABOBOFGREETINGWITHAQUICKLITTLEQUESTIONINGGLANCE\ FROMHISSMALLFATENCIRCLEDEYESTRYTHESETTEESAIDHOLMESRELAPSINGINTOHISARMCHAIRANDPUTTINGHISFI\ NGERTIPSTOGETHERASWASHISCUSTOMWHENINJUDICIALMOODSIKNOWMYDEARWATSONTHATYOUSHAREMYLOVEOFALL\ THATISBIZARREANDOUTSIDETHECONVENTIONSANDHUMDRUMROUTINEOFEVERYDAYLIFEYOUHAVESHOWNYOURRELIS\ HFORITBYTHEENTHUSIASMWHICHHASPROMPTEDYOUTOCHRONICLEANDIFYOUWILLEXCUSEMYSAYINGSOSOMEWHATTO\ EMBELLISHSOMANYOFMYOWNLITTLEADVENTURESYOURCASESHAVEINDEEDBEENOFTHEGREATESTINTERESTTOMEIOB\ SERVEDYOUWILLREMEMBERTHATIREMARKEDTHEOTHERDAYJUSTBEFOREWEWENTINTOTHEVERYSIMPLEPROBLEMPRES\ ENTEDBYMISSMARYSUTHERLANDTHATFORSTRANGEEFFECTSANDEXTRAORDINARYCOMBINATIONSWEMUSTGOTOLIFEI\ TSELFWHICHISALWAYSFARMOREDARINGTHANANYEFFORTOFTHEIMAGINATIONAPROPOSITIONWHICHITOOKTHELIBE\ RTYOFDOUBTINGYOUDIDDOCTORBUTNONETHELESSYOUMUSTCOMEROUNDTOMYVIEWFOROTHERWISEISHALLKEEPONPI\ LINGFACTUPONFACTONYOUUNTILYOURREASONBREAKSDOWNUNDERTHEMANDACKNOWLEDGESMETOBERIGHTNOWMRJAB\ EZWILSONHEREHASBEENGOODENOUGHTOCALLUPONMETHISMORNINGANDTOBEGINANARRATIVEWHICHPROMISESTOBE\ ONEOFTHEMOSTSINGULARWHICHIHAVELISTENEDTOFORSOMETIMEYOUHAVEHEARDMEREMARKTHATTHESTRANGESTAN\ DMOSTUNIQUETHINGSAREVERYOFTENCONNECTEDNOTWITHTHELARGERBUTWITHTHESMALLERCRIMESANDOCCASIONA\ LLYINDEEDWHERETHEREISROOMFORDOUBTWHETHERANYPOSITIVECRIMEHASBEENCOMMITTEDASFARASIHAVEHEARD\ ITISIMPOSSIBLEFORMETOSAYWHETHERTHEPRESENTCASEISANINSTANCEOFCRIMEORNOTBUTTHECOURSEOFEVENTS\ ISCERTAINLYAMONGTHEMOSTSINGULARTHATIHAVEEVERLISTENEDTOPERHAPSMRWILSONYOUWOULDHAVETHEGREAT\ KINDNESSTORECOMMENCEYOURNARRATIVEIASKYOUNOTMERELYBECAUSEMYFRIENDDRWATSONHASNOTHEARDTHEOPE\ NINGPARTBUTALSOBECAUSETHEPECULIARNATUREOFTHESTORYMAKESMEANXIOUSTOHAVEEVERYPOSSIBLEDETAILF\ ROMYOURLIPSASARULEWHENIHAVEHEARDSOMESLIGHTINDICATIONOFTHECOURSEOFEVENTSIAMABLETOGUIDEMYSE\ LFBYTHETHOUSANDSOFOTHERSIMILARCASESWHICHOCCURTOMYMEMORYINTHEPRESENTINSTANCEIAMFORCEDTOADM\ ITTHATTHEFACTSARETOTHEBESTOFMYBELIEFUNIQUE > /* It is right now. */ > for i:=2 to 25 do for> print "Period:",i,"CI:",CoincidenceIndex(Decimation(vt3,1,i)); for> end for; Period: 2 CI: 0.0402615184500581912781543095776 Period: 3 CI: 0.0406375735066542865985762921696 Period: 4 CI: 0.0406994354949745284317775024095 Period: 5 CI: 0.0375107665805340223944875107666 Period: 6 CI: 0.0378646803227808814400993171943 Period: 7 CI: 0.0618792971734148204736440030557 Period: 8 CI: 0.0392482034273079049198452183527 Period: 9 CI: 0.0411764705882352941176470588236 Period: 10 CI: 0.0372101073035652474904811353410 Period: 11 CI: 0.0382916053019145802650957290133 Period: 12 CI: 0.0369538077403245942571785268414 Period: 13 CI: 0.0431971789597414046429620922715 Period: 14 CI: 0.0663021189336978810663021189337 Period: 15 CI: 0.0356025039123630672926447574335 Period: 16 CI: 0.0429669832654907281772953414745 Period: 17 CI: 0.0327700972862263184843830005120 Period: 18 CI: 0.0350282485875706214689265536723 Period: 19 CI: 0.0454545454545454545454545454546 Period: 20 CI: 0.0412299091544374563242487770790 Period: 21 CI: 0.0627450980392156862745098039216 Period: 22 CI: 0.0459183673469387755102040816327 Period: 23 CI: 0.0453283996299722479185938945421 Period: 24 CI: 0.0393939393939393939393939393940 Period: 25 CI: 0.0387596899224806201550387596899 > /* Period 7 is the one */ > SortedFreqDist(Decimation(vt3,1,7))[1]; <0.136363636702299118041992187500, X> > SortedFreqDist(Decimation(vt3,2,7))[1]; <0.168831169605255126953125000000, A> > SortedFreqDist(Decimation(vt3,3,7))[1]; <0.123376623727381229400634765625, S> > SortedFreqDist(Decimation(vt3,4,7))[1]; <0.103896103799343109130859375000, T> > SortedFreqDist(Decimation(vt3,5,7))[1]; <0.149350648745894432067871093750, E> > SortedFreqDist(Decimation(vt3,6,7))[1]; <0.116883116774260997772216796875, G> > SortedFreqDist(Decimation(vt3,7,7))[1]; <0.129870129749178886413574218750, I> > /* XASTEGI for the images of E, possibly. */ > alphabet[Index(alphabet,"X")-4]; T > alphabet[Index(alphabet,"A")-4+26]; W > alphabet[Index(alphabet,"S")-4]; O > alphabet[Index(alphabet,"T")-4]; P > alphabet[Index(alphabet,"E")-4]; A > alphabet[Index(alphabet,"G")-4]; C > alphabet[Index(alphabet,"I")-4]; E > V3:=VigenereCryptosystem(7); > k3:=V3!"TWOPACE"; > Enciphering(InverseKey(k3),Encoding(V3,vt3)); MYDUARFELLEWSAIDSXERLOCKXOLMESAIWESATODEITHERIIDEOFTXEFIREIDHISLODWINGSATRAKERSTHEETLIFUI\ SINFIDITELYSJRANGERJHANANYJHINGWHYCHTHEMYNDOFMADCOULDIDVENTWEMOULDNOJDARETOSONCEIVUTHETHI\ DGSWHICXAREREABLYMERESOMMONPBACESOFUXISTENSEIFWECEULDFLYEUTOFTHQTWINDOMHANDINXANDHOVUROVE\ RTXISGREAJCITYGEDTLYREMEVETHEREOFSANDFEEPINAJTHEQUEURTHINGIWHICHAHEGOINGENTHESTHANGECOYNC\ IDENSESTHEPBANNINGITHECROISPURPOIESTHEWENDERFUBCHAINSEFEVENTIWORKINWTHROUGXGENERAJIONANDB\ EADINGJOTHEMOITOUTREHESULTSYTWOULDCAKEALLVICTIONMITHITSSONVENTYONALITYESANDFERESEENSONCLU\ SYONSMOSJSTALEADDUNPROVITABLEQNDYETIQMNOTCODVINCEDEFITIANIWEREDTXECASESMHICHCOCETOLIGXTIN\ THEFAPERSAHEASARUBEBALDEDOUGHANTVULGARUNOUGHWUHAVEINEURPOLISEREPORJSREALIIMPUSHETTOITSENT\ REMELYMITSANTYETTHEHESULTIIITMUSTRECONFEISEDNEIJHERFASSINATINWNORARTYSTICACURTAINSULECTIO\ DANDDISSRETIONCUSTBEUIEDINPREDUCINGQREALISJICEFFESTREMARAEDHOLMUSTHISIIWANTINWINTHEPELICE\ REFORTWHEHEMORESJRESSISBAIDPERXAPSUPODTHEPLAJITUDESEFTHEMAWISTRATUTHANUPENTHEDEJAILSWHYCH\ TOANEBSERVEHCONTAIDTHEVITQLESSENSEOFTHEMHOLEMAJTERDEPUNDUPONYTTHEREYSNOTHIDGSOUNNQTURALAI\ THECOMCONPLACU > /* Wrong again! The 4th letter of the key is wrong. */ > SortedFreqDist(Decimation(vt3,4,7))[2]; <0.103896103799343109130859375000, Y> > alphabet[Index(alphabet,"Y")-4]; U > k3:=V3!"TWOUACE"; > Enciphering(InverseKey(k3),Encoding(V3,vt3)); MYDPARFELLZWSAIDSSERLOCKSOLMESADWESATOYEITHERDIDEOFTSEFIREIYHISLODRINGSATMAKERSTCEETLIFPI\ SINFIYITELYSERANGEREHANANYEHINGWHTCHTHEMTNDOFMAYCOULDIYVENTWEHOULDNOEDARETONONCEIVPTHETHI\ YGSWHICSAREREAWLYMERENOMMONPWACESOFPXISTENNEIFWECZULDFLYZUTOFTHLTWINDOHHANDINSANDHOVPROVE\ RTSISGREAECITYGEYTLYREMZVETHERZOFSANDAEEPINAETHEQUEPRTHINGDWHICHACEGOINGZNTHESTCANGECOTNC\ IDENNESTHEPWANNINGDTHECRODSPURPODESTHEWZNDERFUWCHAINSZFEVENTDWORKINRTHROUGSGENERAEIONANDW\ EADINGEOTHEMODTOUTRECESULTSTTWOULDXAKEALLQICTIONHITHITSNONVENTTONALITTESANDFZRESEENNONCLU\ STONSMOSESTALEAYDUNPROQITABLELNDYETILMNOTCOYVINCEDZFITIANDWEREDTSECASESHHICHCOXETOLIGSTIN\ THEAAPERSACEASARUWEBALDEYOUGHANOVULGARPNOUGHWPHAVEINZURPOLINEREPORESREALIDMPUSHEOTOITSEIT\ REMELTMITSANOYETTHECESULTIDITMUSTMECONFEDSEDNEIEHERFASNINATINRNORARTTSTICACPRTAINSPLECTIO\ YANDDISNRETIONXUSTBEUDEDINPRZDUCINGLREALISEICEFFENTREMARVEDHOLMPSTHISIDWANTINRINTHEPZLICE\ REAORTWHECEMORESERESSISWAIDPERSAPSUPOYTHEPLAEITUDESZFTHEMARISTRATPTHANUPZNTHEDEEAILSWHTCH\ TOANZBSERVECCONTAIYTHEVITLLESSENNEOFTHEHHOLEMAETERDEPPNDUPONTTTHERETSNOTHIYGSOUNNLTURALAD\ THECOMXONPLACP > /* Still wrong! */ > SortedFreqDist(Decimation(vt3,4,7))[3]; <0.0974025977775454521179199218750, X> > alphabet[Index(alphabet,"X")-4]; T > /* I can see that this will not be right either. The plain text is clearly > MYDEARFELLOWSAIDSHERLOCK... . The 4th letter of vt3 is a J, and it must represent E, > meaning that A is represented by F. The key is TWOFACE, and in this particular > decimation of the plaintext E is only the 5th most frequent letter! */ > SortedFreqDist(Decimation(vt3,4,7))[5]; <0.0844155848026275634765625000000, J> > k3:=V3!"TWOFACE"; > Enciphering(InverseKey(k3),Encoding(V3,vt3)); MYDEARFELLOWSAIDSHERLOCKHOLMESASWESATONEITHERSIDEOFTHEFIREINHISLODGINGSATBAKERSTREETLIFEI\ SINFINITELYSTRANGERTHANANYTHINGWHICHTHEMINDOFMANCOULDINVENTWEWOULDNOTDARETOCONCEIVETHETHI\ NGSWHICHAREREALLYMERECOMMONPLACESOFEXISTENCEIFWECOULDFLYOUTOFTHATWINDOWHANDINHANDHOVEROVE\ RTHISGREATCITYGENTLYREMOVETHEROOFSANDPEEPINATTHEQUEERTHINGSWHICHAREGOINGONTHESTRANGECOINC\ IDENCESTHEPLANNINGSTHECROSSPURPOSESTHEWONDERFULCHAINSOFEVENTSWORKINGTHROUGHGENERATIONANDL\ EADINGTOTHEMOSTOUTRERESULTSITWOULDMAKEALLFICTIONWITHITSCONVENTIONALITIESANDFORESEENCONCLU\ SIONSMOSTSTALEANDUNPROFITABLEANDYETIAMNOTCONVINCEDOFITIANSWEREDTHECASESWHICHCOMETOLIGHTIN\ THEPAPERSAREASARULEBALDENOUGHANDVULGARENOUGHWEHAVEINOURPOLICEREPORTSREALISMPUSHEDTOITSEXT\ REMELIMITSANDYETTHERESULTISITMUSTBECONFESSEDNEITHERFASCINATINGNORARTISTICACERTAINSELECTIO\ NANDDISCRETIONMUSTBEUSEDINPRODUCINGAREALISTICEFFECTREMARKEDHOLMESTHISISWANTINGINTHEPOLICE\ REPORTWHEREMORESTRESSISLAIDPERHAPSUPONTHEPLATITUDESOFTHEMAGISTRATETHANUPONTHEDETAILSWHICH\ TOANOBSERVERCONTAINTHEVITALESSENCEOFTHEWHOLEMATTERDEPENDUPONITTHEREISNOTHINGSOUNNATURALAS\ THECOMMONPLACE > exit;