|
28 December 1997: Link to full manual
This is Appendix F of the US Army's Field Manual FM 34-40-2, Basic Cryptanalysis, September, 1990.
Original, since withdrawn, was once at: http://www.atsc-army.org/cgi-win/$atdl.exe/fm/34-40-2/appf.pdf
Transcribed from PDF-format December 19, 1996. Typos corrected December 29, 1996.
F-1. Program Support
This program supports the development of FM 34-40-2, Basic Cryptanalysis. It gives the capability to encipher and decipher messages in monoalphabetic and polyalphabetic substitution systems, produce a variety of statistical data about the encrypted messages, and print the results or save them to disk. Because of its limited purpose, the program does not support on-screen analysis. The printed results can be used off-line to aid in analysis, however. The program should be particularly useful in preparing examples and exercises for training cryptanalytic techniques.
F-2. On-screen Analysis
The logical structure is present in the program to support on-screen analysis, if desired. The coding that now sends results to disk or printer can be modified to display on screen as well. Lines 6060 through 6780 provide the basis for this. This code together with the alphabet entry subroutines in lines 3920 through 5760 can be used to enter partial trial recoveries and see the results for both monoalphabetic and polyalphabetic systems.
F-3. Program Format
The listing has been specially formatted to make it easy to follow the program logic. Each statement in multiple statement numbered lines has been printed on a separate line with each follow-on statement indicated by the statement separator (colon) at the beginning of the line. FOR-NEXT commands have been indented to show the level and structure of each. Similarly, the parts of IF...THEN...ELSE statements have been printed on separate lines and then indented to show their structure clearly. If the program is typed in by hand, the statements in a single numbered line should be entered continuously, not on separate lines in most versions of BASIC. Indentation of FOR-NEXT structures can be preserved, if desired, but not for IF...THEN...ELSE statements.
100 ' CRYPTANALYSIS SUPPORT PROGRAM 120 ' Version 1.0 140 ' 4 October 1988 160 ' 180 ' Developed in support of FM 34-40-2, Basic Cryptanalysis to provide 200 ' accurate encryption, decryption, frequency counts, and statistics for use 220 ' in the manual. It can be used for other applications. 240 ' 260 ' The program was written in GW-BASIC. 280 ' It is readily adaptable to any computers that run 300 ' GW-BASIC. It can easily be converted to run in other BASIC languages. 320 ' 340 ' As written, the program will print on a dot matrix printer with the name 360 ' PRN1 that uses standard Epson control codes. If necessary, change the 380 ' values in the *** Printer Setup *** section for the particular printer 400 ' to be used. 420 ' 440 ' *** Printer Setup *** 460 PRINTER$="PRN1" 480 FORMFEED$=CHR$(12) 500 CRLF$=CHR$(13)+CHR$(10) ' (not used in 1.0) 520 CONDENSED$=CHR$(15) ' (not used in 1.0) 540 DC2$=CHR$(18) ' Cancels condensed mode (not used in 1.0) 560 ELITE$=CHR$(27)+"M" ' (not used in 1.0) 580 PICA$=CHR$(27)+"P" ' (not used in 1.0) 600 ' 620 ' *** Initialize Variables *** 640 ' DIM PTEXTD$(25), PTEXTI$(25), CTEXTD$(25), CTEXTI$(25) 660 ' Plain and ciphertext may be stored in two forms: display and internal. 680 ' Display forms (PTEXTD$() and CTEXTD()) are as typed with spaces. 700 ' Internal forms (PTEXTI$() and CTEXTI$()) have spaces, and nonliteral 720 ' characters stripped away. All frequency counts and ICs are performed on 740 ' CTEXTI$() strings. Up to 25 lines of text are allowed, as written. 760 ' Additional lines of text may be used if all uses of "25" are increased 780 ' in the DIM statement in line 640. 800 DIM MFREQ(26), PFREQ(20,27), DIFREQ(26,26), PHIMONO,PHIPERI(20), PHIDIG, PMIXFREQ(20,27), SET 1(26), SET 2(27), MATCH (27), PERPHISUM(20), PERTOTLTR(20) 820 ' Sets up monographic, periodic, and digraphic frequency, IC tables. Up 840 ' to 20 alphabets are allowed for periodic frequencies, as written. The 860 ' number of alphabets can be increased by increasing all uses of "20" in 880 ' the DIM statements in line 800. 900 DIM PCOMP$, CCOMP$(200) ' Variables for plain and cipher components with up 920 ' to 200 cipher component sequences for long running key aperiodics. The 940 ' length of the key may be increased by increasing the "200" in the DIM 960 ' statement in line 900. 1000 ' 1020 KEY OFF ' Turns off prompts on bottom of screen. 1040 ' 1160 ' *** Main Menu *** 1180 CLS 1200 PRINT " CRYPTANALYSIS SUPPORT PROGRAM" 1220 PRINT :PRINT 1240 PRINT " 1. Enter text ";STATUS$(1) 1260 PRINT " 2. Encipher text ";STATUS$(2) 1280 PRINT " 3. Decipher text ";STATUS$(3) 1300 PRINT " 4. Print text ";STATUS$(4) 1320 PRINT " 5. Save text to disk ";STATUS$(5) 1340 PRINT " 6. Calculate frequency counts, ICs ";STATUS$(6) 1360 PRINT " 7. Print frequency counts, ICs ";STATUS$(7) 1380 PRINT " 8. Save frequency counts, ICs to disk ";STATUS$(8) 1400 PRINT " 9. Find repeats ";STATUS$(9) 1420 PRINT " 10. Quit" 1440 PRINT :PRINT 1460 ' 1480 ' *** Main Menu Control *** 1500 INPUT "Enter your choice: ",SELECTION 1520 ON SELECTION GOSUB 1600,3000,3480,6080,6380,6840,8600,9960,10240,10980 1540 GOTO 1180 1560 ' 1580 ' *** Text Entry Subroutine *** 1600 CLS 1620 PRINT " TEXT ENTRY MENU" 1640 PRINT :PRINT :PRINT 1660 PRINT " 1. Enter plaintext from disk 1680 PRINT " 2. Enter ciphertext from disk 1700 PRINT " 3. Enter plaintext from keyboard 1720 PRINT " 4. Enter ciphertext from keyboard 1740 PRINT " 5. Return to Main Menu 1760 PRINT :PRINT 1780 INPUT "Enter your choice: ", CHOICE 1800 ON CHOICE GOTO 1860,2040,2220,2440,2600 1820 ' 1840 ' *** Plaintext Disk Entry *** 1860 INPUT ~'Enter input filename, for example, P;:SAMPLE.TXT ",INFILE$ 1880 OPEN INFILE$ FOR INPUT AS #1 1900 NRLINES=0 1920 NRLINES=NRLINES+1 1940 INPUT #1, PTEXTD$(NRLINES) 1960 IF EOF(1) THEN STATUS$(1)=" (PLAINTEXT ENTERED)" :CLOSE #1 :RETURN 1980 GOTO 1920 2000 ' 2020 ' *** Ciphertext Disk Entry *** 2040 INPUT "Enter input filename, for example, A:SAMPLE.TXT ",INFILE$ 2060 OPEN INFILE$ FOR INPUT AS #1 2080 NRLINES=0 2100 NRLINES=NRLINES+1 2120 INPUT #1,CTEXTD$(NRLINES) 2140 IF EOF(1) THEN CLOSE #1 :STATUS$=" (CIPHERTEXT ENTERED)" :GOTO 2660 ' Branches to internal text preparation. 2160 GOTO 2100 2180 ' 2200 ' *** Plaintext Keyboard Entry *** 2220 PRINT "Type a line of text. Use lower case letters only." 2240 PRINT "Use no commas in the text. When you are through," 2260 PRINT "type END on a new line." 2280 NRLINES=0 2300 LINE INPUT T$ 2320 IF T$="END" OR T$="end" THEN STATUS$(1)=" (PLAINTEXT ENTERED)" :RETURN 2340 NRLINES=NRLINES+1 2360 PTEXTD$(NRLINES)=T$ 2380 GOTO 2300 2400 ' 2420 ' *** Ciphertext Keyboard Entry *** 2440 PRINT "Type a line of text. Use CAPITAL letters only." 2460 PRINT "When you are through, type END on a new line." 2480 NRLINES=0 2500 INPUT T$ 2520 IF T$="END" OR T$="end" THEN STATUS$(1)=" (CIPHERTEXT ENTERED)" :GOTO 2660 2540 NRLINES=NRLINES+1 2560 CTEXTD$(NRLINES)=T$ 2580 GOTO 2500 2600 RETURN 2620 ' 2640 ' *** Preps Ciphertext in Internal Format *** 2660 FOR TEXTLINE=1 TO NRLINES 2680 T$=CTEXTD$(TEXTLINE) 2700 POSN=0 2720 POSN=POSN+1 :IF POSN>LEN(T$) THEN 2800 2740 C$=MID$(T$,POSN,1) 2760 IF (ASC(C$)<65 OR ASC(C$)>90) AND C$<>"." THEN GOSUB 2900 2780 GOTO 2720 2800 CTEXTI$(TEXTLINE)=T$ 2820 NEXT TEXTLINE 2840 RETURN 2860 ' 2880 ' *** Subroutine to Strip Nonliteral Characters From Ciphertext *** 2900 T$=MID$(T$,1,POSN-1)+MID$(T$,POSN+1,LEN(T$)-POSN) 2920 POSN=POSN-1 2940 RETURN 2960 ' 2980 ' *** Encipherment Subroutine *** 3000 GOSUB 3940 3020 CYCLEPOS=0 3040 FOR LNE=1 TO NRLINES :CTEXTD$(LNE)=" :KTEXTD$(LNE)=" :NEXT LNE 3060 FOR LNE=1 TO NRLINES 3080 FOR CHARPOS=1 TO LEN(PTEXTD$(LNE)) 3100 PCHAR$=MID$(PTEXTD$(LNE),CHARPOS,1) 3120 IF PCHAR$=" " THEN CCHAR$=" :KCHAR$=" :GOTO 3320 3140 CYCLEPOS=CYCLEPOS+1 :IF CYCLEPOS>PERIOD THEN CYCLEPOS=1 3160 KCHAR$=MID$(REPEATKEY$,CYCLEPOS,1) 3180 IF ASC (PCHAR$) >64 AND ASC(PCHAR$)<91 THEN PCHAR$=CHR$(ASC(PCHAR$)+32) 3200 IF ASC(PCHAR$)<97 OR ASC(PCHAR$)>122 THEN PCHAR$="." 3220 IF PCHAR$="." THEN CCHAR$="." :GOTO 3320 3240 FOR ALPHCHAR=1 TO 26 3260 IF PCHAR$=MID$(PCOMP$,ALPHCHAR,1) THEN CCHAR$=MID$(CCOMP$(CYCLEPOS),ALPHCHAR,1) :GOTO 3320 3280 NEXT ALPHCHAR 3300 CCHAR$="." 3320 CTEXTD$(LNE)=CTEXTD$(LNE)+CCHAR$ :KTEXTD$(LNE)=KTEXTD$(LNE)+KCHAR$ 3340 NEXT CHARPOS 3360 NEXT LNE 3380 GOSUB 2660 3400 STATUS$(2)=" (ENCIPHEREMENT COMPLETED)" 3420 RETURN 3440 ' 3460 ' *** Decipherment Subroutine *** 3480 GOSUB 3940 3500 CYCLEPOS=0 3520 FOR LNE=1 TO NRLINES :PTEXTD$(LNE)="": NEXT LNE 3540 FOR LNE=1 TO NRLINES 3560 FOR CHARPOS=1 TO LEN(CTEXTD$(LNE)) 3580 CCHAR$=MID$(CTEXTD$(LNE),CHARPOS,1) 3600 IF CCHAR$=" " THEN PCHAR$=" " :GOTO 3780 3620 CYCLEPOS=CYCLEPOS+1 IF CYCLEPOS>PERIOD THEN CYCLEPOS=1 3640 IF ASC(CCHAR$)>96 AND ASC(CCHAR$)<123 THEN CCHAR$=CHR$(ASC(CCHAR$)-32) 3660 IF ASC(CCHAR$)<65 OR ASC(CCHAR$)>96 THEN CCHAR$="." 3680 IF CCHAR$="." THEN PCHAR$="." :GOTO 3780 3700 FOR ALPHCHAR=1 TO 26 3720 IF CCHAR$=MID$(CCOMP$(CYCLEPOS),ALPHCHAR,1) THEN PCHAR$=MID$(PCOMP$,ALPHCHAR,1 :GOTO 3780 3740 NEXT ALPHCHAR 3760 PCHAR$="." 3780 PTEXTD$(LNE)=PTEXTD$(LNE)+PCHAR$ 3800 NEXT CHARPOS 3820 NEXT LNE 3840 GOSUB 2660 3860 STATUS$(3)=" (DECIPHERMENT COMPLETED)" 3880 RETURN 3900 ' 3920 ' *** Alphabet Entry Subroutine *** 3940 PCOMP$="abcdefghijklmnopqrstuvwxyz" 3960 CCOMPO$="ABCDEFGHIJKLMNOPQRSTUVWXYZ" 3980 RKEY$="AAAAAAAAAAAAAAAAAAAA" 4000 PERIOD=1 4020 CLS 4040 PRINT "Select type of system:" :PRINT 4060 PRINT " 1. Monoalphabetic uniliteral" 4080 PRINT " 2. Periodic polyalphabetic" 4100 PRINT " 3. Aperiodic polyalphabetic" 4120 PRINT :PRINT 4140 INPUT "Enter your choice: ", SELECTION 4160 ON SELECTION GOSUB 4240,4860,6020 4180 RETURN 4200 ' 4220 ' *** Monoalphabetic Alphabet Entry Subroutine *** 4240 CLS:PLFAG=0:CIFLAG=0:DONEFLAG=0 4260 PRINT TAB(5);"Present alphabet is--":PRINT 4280 PRINT TAB(10);"P: "; :FOR N=1 TO 26 :PRINT MID$(PCOMP$,N,1);" "; :NEXT N 4300 PRINT TAB(10);"C: "; :FOR N=1 TO 26 :PRINT MID$(CCOMPOS$,N,1;" "; :NEXT N 4320 PRINT :PRINT 4340 PRINT TAB(20);"1. Change plain component" 4360 PRINT TAB(20);"2. Change cipher component" 4380 PRINT TAB(20);"3. Change specific key" 4400 PRINT TAB(20);"4. Accept alphabet as shown" 4420 PRINT :PRINT TAB(18);"Enter your choice: "; 4440 INPUT CHOICE 4460 ON CHOICE GOSUB 4520,4580,4640,4500. 4480 IF DONEFLAG=1 THEN CCOMP$(1)=CCOMPO$ :RETURN ELSE GOTO 4240 ' Exit if done 4500 DONEFLAG=1 :RETURN 4520 ROW=3 :COLUMN=11 :PLFAG=1 :GOSUB 5640 4540 PCOMP$=COMP$ 4560 RETURN 4580 ROW=4 :COLUMN=11 :CIFLAG=1 :GOSUB 5640 4600 CCOMPO$=COMP$ 4620 RETURN 4640 LOCATE 11,10:X=SCREEN (3,13): PRINT "Type the specific key: ";CHR$(X-32); " of plaintext = ? of ciphertext." 4660 LOCATE 11,50,1 4680 X$=INKEY$ :IF X$=" " THEN 4680 4700 IF ASC(X$)>96 AND ASC(X$)<123 THEN X$=CHR$(ASC(X$)-32) 4720 FOR N=1 TO 26: IF X$=MID$(CCOMPO$,N,1) THEN 4780 4740 NEXT N 4760 PRINT "CHARACTER NOT FOUND IN CIPHER COMPONENT" :GOTO 4640 4780 TCOMP$=RIGHT$(CCOMPO$,27-N)+LEFT$(CCOMPO$,N-1) :CCOMPO$=TCOMP$ 4800 RETURN 4820 ' 4840 ' *** Periodic and Aperiodic Alphabet Entry Subroutine *** 4860 CLS :DONEFLAG=0 :PLFLAG=0 :CIFLAG=0 4880 PRINT TAB(5);"Plain component is--" 4900 PRINT TAB(10);"P: " :FOR N=1 TO 26 :PRINT MID$(PCOMP$,N,1);" "; :NEXT N :PRINT 4920 PRINT TAB(5);"Cipher component is--" 4940 PRINT TAB(10);"C: "; :FOR N=1 TO 26 :PRINT MID$(CCOMPO$,N,1);" "; :NEXT N :PRINT :PRINT 4960 IF AFLAG=0 THEN PRINT TAB(5);"Length of pERIOD IS: ";PERIOD ELSE PRINT TAB(5);"Length of key is: ";PERIOD 4980 X=SCREEN(2,13) 5000 IF AFLAG=0 THEN REPEATKEY$=LEFT$(RKEY$,PERIOD) 5020 IF AFLAG=0 THEN PRINT TAB(5);"Repeating key is ";CHR$(X-32);" of plaintext = ";REPEATKEY$ :PRINT :ELSE PRINT TAB (5);"Long running key is: ";REPEATKEY$ :PRINT 5040 PRINT :PRINT 5060 PRINT TAB(20);"1. Change plain component" 5080 PRINT TAB(20):"2. Change cipher component" 5100 IF AFLAG=0 THEN PRINT TAB (20);"3. Change repeating key" ELSE PRINT TAB(20);"3. Generate long running key" 5120 IF AFLAG=0 THEN PRINT TAB(20);"4. Show complete matrix" ELSE PRINT TAB(20);"4. Accept alphabets" 5140 PRINT :PRINT TAB(18);"Enter your choice: "; 5160 INPUT CHOICE 5180 ON CHOICE GOSUB 5220,5260,5300,5420 5200 IF DON EFLAG=1 THEN RETURN ELSE GOTO 4860 5220 ROW=2 :COLUMN=11 :PLFLAG=1 :GOSUB 5640 5240 PCOMP$=COMP$ :RETURN 5260 ROW=4 :COLUMN=11 :CIFLAG=1 :CMIXFLAG=1 :GOSUB 5640 5280 CCOMPO$=COMP$ :RETURN 5300 IF AFLAG=1 THEN 5820 ELSE LOCATE 7,39 :INPUT RKEY$ 5320 PERIOD=LEN(RKEY$) 5340 FOR N=1 TO PERIOD: FOR P=1 TO 26 :IF MID$(RKEY$,N,1)=MID$(CCOMPO$,P,1) THEN 5380 5360 NEXT P 5380 CCOMP$(N)=RIGHT$(CCOMPO$,27-P)+LEFT$(CCOMPO$,P-1) :NEXT N 5400 RETURN 5420 CLS :IF AFLAG=1 THEN 4500 5440 PRINT TAB(9);"P: "; :FOR N=1 TO 26 :PRINT MID$(PCOMP$,N,1);" "; :NEXT N :PRINT :PRINT TAB(13);"---------------------------------------------------" 5460 FOR P=1 TO PERIOD 5480 PRINT TAB(9);"C";CHR$(48+P);": "; :FOR N=1 TO 26 :PRINT MID$(CCOMP$(P),N,1);" "; :NEXT N :PRINT 5500 NEXT P 5520 PRINT TAB(20);"1. Change matrix" 5540 PRINT TAB(20);"2. Accept matrix" 5560 INPUT" Enter your choice: ";CHOICE 5580 ON CHOICE GOTO 4860,4500 5600 ' 5620 ' *** Reads in Edited Plain or Cipher Component From Screen *** 5640 LOCATE ROW, COLUMN :INPUT DUMMY$ ' DUMMY$ is not used as text is read from screen 5660 COMP$=" " 5680 FOR N=13 TO 63 STEP 2 :X=SCREEN(ROW,N) :COMP$=COMP$+CHR$(X) 5700 IF PLFLAG=1 AND (X<96 OR X>122) AND X<>46 THEN BEEP :GOTO 5640 5720 IF CIFLAG=1 AND (X<65 OR X>90) THEN BEEP :GOTO 5640 5740 NEXT N 5760 RETURN 5780 ' 5800 ' *** Aperiodic Long-Running Key Generation Subroutine *** 5820 CLS 5840 RANDOMIZE 5860 INPUT "Enter the number of alphabets (up to 200): ";PERIOD 5880 FOR N=1 TO PERIOD 5900 LRK$=LRK$+CHR$(INT(RND*26)+65) 5920 NEXT N 5940 REPEATKEY$=LRK$ :RKEY$=LRK$ 5960 GOTO 5340 5980 ' 6000 ' *** Sets Flag Indicating Long-Running Key System *** 6020 AFLAG=1 :GOTO 4806 6040 ' 6060 ' *** Text Print Subroutine *** 6080 CLS 6100 PRINT "IS PRINTER READY (Y/N)? " 6120 X$=INKEY$ :IF X$=" " THEN 6120 6140 IF X$="N" OR X$="n" THEN RETURN 6160 OUTFILE$=PRINTER$ 6180 GOSUB 6440 6200 PRINT #1,FORMFEED$;FORMFEED$ 6220 CLOSE #1 6240 STATUS$(4)=" (TEXT PRINTED)" 6260 IF PRINTER$<>"CON" THEN 6320 6280 PRINT "PRESS ANY KEY TO CONTINUE" 6300 GO$=INKEY$ :IF GO$=' THEN 6300 6320 RETURN 6340 ' 6360 ' *** Text Save to Disk Subroutine *** 6380 CLS 6400 PRINT "Enter complete disk filename for the save text, for example," 6420 INPUT"A:MYSAVE.TXT ";OUTFILE$ 6440 OPEN OUTFILE$ FOR OUTPUT AS #1 6460 TEXTCOUNT=0 6480 FOR N=1 TO NRLINES 6500 PRINT #1,PTEXTD$(N) 6520 PRINT #1,CTEXTD$(N) 6540 PRINT #1,KTEXTD$(N) 6560 TEXTCOUNT=TEXTCOUNT+LEN(CTEXTI$(N)) 6580 PRINT +1, 6600 NEXT N 6620 IF PERIOD>20 THEN 6720 6640 PRINT#1,PCOMP$ 6660 FOR N=1 TO PERIOD 6680 PRINT #1,CCOMP$(N) 6700 NEXT N 6720 IF OUTFILE$=PRINTER$ OR FILEFLAG=1 THEN RETURN 6740 CLOSE #1 6760 IF OUTFILE$<>PRINTER$ THEN STATUS$(5)=" (TEXT SAVED)" 6780 RETURN 6800 ' 6820 ' *** Frequency Count, IC Subroutine *** 6840 CLS 6860 PRINT "Select the routine you want to run:" 6880 PRINT:PRINT 6900 PRINT " 1. Monographic frequencies and ICs"+STAT$(1) 6920 PRINT " 2. Digraphic frequencies and ICs"+STAT$(2) 6940 PRINT " 3. Periodic frequencies and ICs"+STAT$(3) 6960 PRINT " 4. Chi test"+STAT$(4) 6980 PRINT " 5. RETURN TO MAIN MENU" 7000 INPUT " Your choice: ",CHOICE$ 7020 IF ASC (CHOICE$)<49 OR ASC(CHOICE$)>53 THEN 7000 7040 ON (ASC(CHOICE$)-48) GOSUB 7120,7440,7900,11120, 1180 7060 GOTO 6840 7080 ' 7100 ' *** Monographic Frequency and IC Subroutine *** 7120 FOR LINE=1 TO NRLINES 7140 FOR CHARPOS=1 TO LEN(CTEXTI$(LNE)) 7160 NXTLTR$=MID$(CTEXTI$(LNE),CHARPOS,1) 7180 Z=ASC(NXTLTR$)-64 7200 MFREQ(Z)=MFREQ(Z)+1 7220 NEXT CHARPOS 7240 NEXT LNE 7260 FOR Z=1 TO 26 7280 TOTLTRS=TOTLTRS+MFREQ(Z) 7300 PHISUM=PHISUM+(MFREa(Z)*(MFREQ(Z)-1)) 7320 NEXT Z 7340 PHIMONO=26*PHISUM/(TOTLTRS*(TOTLTRS-1)) 7360 MFLAG=1 :STAT$(1)=" (COMPLETED)" :STATUS$(6)=" (COMPLETED)" 7380 RETURN 7400 ' 7420 ' *** Digraphic Frequency and IC *** 7440 FOR LNE=1 TO NRLINES 7460 IF (LEN(CTEXTI$(LNE))/2-INT(LEN(CTEXTI$(LNE))/2))=0 THEN 7520 7480 CARRY$=RIGHT$(CTEXTI$(LNE),1) :CTEXTI$(LNE)=LEFT$(CTEXTI$(LNE),LEN(CTEXTI$(LNE))-1) 7500 CTEXTI$(LNE+1)=CARRY$+CTEXTI$(LNE+1) 7520 NEXT LNE 7540 FOR LNE=1 TO NRLINES 7560 FOR DIG=1 TO INT(LEN(CTEXTI$(LNE))/2) 7580 LTR1=ASC(MID$(CTEXTI$(LNE),DIG*2-1,1))-64 :LTR2=ASC(MID$(CTEXTI$(LNE),DIG*2,1 ))-64 7600 IF LTR1=-18 OR LTR2=-18 THEN 7640 7620 DIFREQ(LTR1,LTR2)=DIFREQ(LTR1,LTR2)+1 7640 NEXT DIG 7660 NEXT LNE 7680 FOR ROW=1 TO 26 7700 FOR COLUMN=1 TO 26 7720 TOTDIG=TOTDIG+DIFREQ(ROW,COLUMN) 7740 DIPHISUM=DIPHISUM+(DIFREQ(ROW,COLUMN)*(DIFREQ(ROW,COLUMN)-1)) 7760 NEXT COLUMN 7780 NEXT ROW 7800 PHIDIG=676*DIPHISUM/(TOTDIG*(TOTDIG-1))7820 DFLAG=1: :STAT$(2)=" (COMPLETED)" :STATUS$(6)=" (COMPLETED)" 7840 RETURN 7860 ' 7880 ' *** Periodic Frequency, IC Subroute *** 7900 CYCLEPOS=0 7920 INPUT "What period do you want to use? ",PERIOD 7940 FOR N=1 TO PERIOD 7960 FOR M=1 TO 26 7980 PFREQ(N,M)=0 8000 NEXT M 8020 PERPHISUM(N)=0 :PERTOTLTR(N)=0 8040 NEXT N 8060 FOR N=1 TO NRLINES 8080 FOR M=1 TO LEN(CTEXTI$(N)) 8100 CYCLEPOS=CYCLEPOS+1 8120 IF CYCLEPOS>PERIOD THEN CYCLEPOS=1 8140 NXTCHAR$=MID$(CTEXTI$(N),M,1) 8160 Z=ASC(NXTCHAR$)-64 8180 IF Z=-18 THEN Z=27 8200 PFREQ(CYCLEPOS,Z)=PFREQ(CYCLEPOS,Z)+1 8220 NEXT M 8240 NEXT N 8260 FOR M=1 TO PERIOD 8280 FOR N=1 TO 26 8300 PERTOTLTR(M)=PERTOTLTR(M)+PFREQ(M,N) 8320 PERPHISUM(M)=PERPHISUM(M)+(PFREQ(M,N)*(PFREQ(M,N)-1)) 8340 NEXT N 8360 PHIPERI(M)=26*PERPHISUM(M)/(PERTOTLTR(M)*(PERTOTLTR(M)-1)) 8380 NEXT M 8400 PFLAG=1 :STAT$(3)=" (COMPLETED)" :STATUS$(6)=" (COMPLETED)" 8420 IF CMIXFLAG=0 THEN 8540' skips mixed alphabet routine if std sequence 8440 FOR M=1 TO PERIOD 8460 FOR N=1 TO 26 8480 PMIXFREQ(M,N)=PFREQ(M,ASC(MID$(CCOMPO$,N,1))-64) 8500 NEXT N 8520 NEXT M 8540 RETURN 8560 ' 8580 ' *** Mixed Alphabet Periodic Stat Print *** 8600 ALPH$=" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" 8620 CLS 8640 OUTFILE$=PRINTER$ 8660 GOSUB 6440 8680 IF MFLAG=1 THEN GOSUB 8880 8700 IF DFLAG=1 THEN PRINT #1,FORMFEED$ :GOSUB 9080 8720 IF PFLAG=1 THEN PRINT #1,FORMFEED$ :GOSUB 9360 8740 IF CMIXFLAG=1 THEN PRINT #1,FORMFEED$ :GOSUB 9580 8760 PRINT #1,FORMFEED$ 8780 PRINT #1,FORMFEED$ 8800 CLOSE #1 8820 RETURN 8840 ' 8860 ' *** Print Monographic Stats *** 8880 PRINT #1, :PRINT #1, 8900 PRINT #1,ALPH$ 8920 FOR N=1 TO 26 8940 PRINT #1,USING "###";MFREQ(N); 8960 NEXT N 8980 PRINT #1, :PRINT #1, 9000 PRINT #1,"TOTAL LETTERS =";TOTLTRS;" MONOGRAPHIC IC =";PHIMONO 9020 RETURN 9040 ' 9060 ' *** Print Digraphic Stats *** 9080 PRINT #1, :PRINT #1, 9100 PRINT #1, " ";ALPH$ 9120 FOR N=1 TO 26 9140 PRINT #1,CHR$(N+64); 9160 FOR M=1 TO 26 9180 PRINT #1,USING "###";DIFREQ(N,M); 9200 NEXT M 9220 PRINT #1, 9240 NEXT N 9260 PRINT #1, :PRINT #1, 9280 PRINT #1, "TOTAL DIGRAPHS =";TOTDIG;" DIGRAPHIC IC=";PHIDIG 9300 RETURN 9320 ' 9340 ' *** Print Monographic Stats *** 9360 PRINT #1, :PRINT #1, 9380 FOR N=1 TO PERIOD 9400 PRINT #1,ALPH$ 9420 FOR M=1 TO 26 9440 PRINT #1,USING "###";PFREQ(N,M); 9460 NEXT M 9480 PRINT #1, 9500 PRINT #1,"TOTAL LETTERS =";PERTOTLTR(N);" IC=";PHIPERI(N) 9520 PRINT #1, :PRINT #1, 9540 NEXT N 9560 RETURN 9580 PRINT#1, :PRINT #1, 9600 FOR M=1 TO PERIOD 9620 ALPHMIX$(M)=" " 9640 FOR N=1 TO 26 9660 ALPHMIX$(M)=ALPHMIX$(M)+" "+MID$(CCOMPO$,N,1) 9680 NEXT N 9700 NEXT M 9720 FOR M=1 TO PERIOD 9740 PRINT #1,ALPHMIX$(M) 9760 FOR N=1 TO 26 9780 PRINT #1,USING "###";PMIXFREQ(M,N); 9800 NEXT N 9820 PRINT #1, 9840 PRINT #1, "TOTAL LETTERS =";PERTOTLTR(M);" IC =";PHIPERI(M) 9860 PRINT #1, :PRINT #1, 9880 NEXT M 9900 RETURN 9920 ' 9940 ' *** Statistics Save to Disk Subroutine *** 9960 ALPH$=" A B C D E F G H I J K L M O P Q R S T U V W X Y Z" 9980 CLS 10000 PRINT "Enter the complete disk filename for the saved statistics, for example," 10020 INPUT "A:MYSTAT.TXT ";OUTFILE$ 10040 FILEFLAG=1 10060 GOSUB 6440 10080 IF MFLAG=1 THEN GOSUB 8880 10100 IF DFLAG=1 THEN GOSUB 9080 10120 IF PFLAG=1 THEN GOSUB 9360 10140 IF CMIXFLAG=1 THEN GOSUB 9580 10160 CLOSE #1 10180 RETURN 10200 ' 10220 ' *** Subroutine to Find Repeats *** 10240 INPUT "What is the shortest length repeat you want listed?",RPTLEN 10260 OUTFILE$=PRINTER$ 10280 OPEN OUTFILE$ FOR OUTPUT AS #1 10300 IF RPTLEN<2 THEN 10240 10320 FOR TLINE=1 TO NRLINES-1 10340 FOR ALTR=1 TO LEN(CTEXTI$(TLINE)) 10360 IF TLINE<>NRLINES THEN CT$=CTEXTI$(TLINE)+CTEXTI$(TLINE+1) ELSE CT$=CTEXTI$(TLINE) 10380 A$=MID$(CT$,ALTR,RPTLEN) 10400 FOR BLTR=ALTR+2 TO LEN(CTEXTI$(TLINE))+2 :BLINE=TLINE :CTB$=CT$ 10420 IF BLTR>LEN(CTEXTI$(TLINE)) THEN 10480 10440 B$=MID$(CTB$,BLTR,RPTLEN) 10460 IF A$=B$ THEN GOSUB 10800 10480 NEXT BLTR 10500 IF TLINE=NRLINES THEN 10660 10520 FOR BLINE=TLINE+1 TO NRLINES 10540 IF BLINE<>NRLINES THEN CTB$=CTEXTI$(BLINE)+CTEXTI$(BLINE+1) ELSE CTB$=CTEXTI$(BLINE) 10560 FOR BLTR=1 TO LEN(CTEXTI$(BLINE)) 10580 B$=MID$(CTB$,BLTR,RPTLEN) 10600 IF A$=B$ THEN GOSUB 10800 10620 NEXT BLTR 10640 NEXT BLINE 10660 NEXT ALTR 10680 NEXT TLINE 10700 PRINT #1, FORMFEED$,FORMFEED$ 10720 CLOSE #1 10740 RETURN 10760 ' 10780 ' *** Subroutine to Check Length of Repeat and Print It *** 10800 LONGER=RPTLEN 10820 PRINT A$ 10840 LONGER=LONGER+1 10860 IF MID$(CT$,ALTR,LONGER)=MID$(CTB$,BLTR,LONGER) THEN 10840' Try it longer 10880 LONGER=LONGER-1 ' Nope, too long 10900 PRINT #1,MID$(CT$,ALTR,LONGER);" AT LINE";TLINE;", LETTER";ALTR; " AND AT LINE";BLINE;", LETTER";BLTR 10920 RETURN 10940 ' 10960 ' *** Quit Subroutine *** 10980 CLS 11000 INPUT "Are you sure you want to quit (Y/N)? ",CHOICE$ 11020 IF CHOICE$ <>"Y" AND CHOICE$ <> "y" THEN 1180 11040 KEY ON ' restores bottom of screen prompts 11060 END 11080 ' 11100 ' *** Chi Test Subroutine *** 11120 PRINT "Do you want to print results or save to disk as text file?" 11140 INPUT "Enter P for printer, D for disk, or Q to quit.",S$ 11160 IF S$="P" OR S$="p" THEN OUTFILE$=PRINTER$ :GOTO 11240 11180 IF S$="Q" OR S$="q" THEN RETURN 11200 IF S$<>"D" AND S$<>"d" THEN 11140 11220 INPUT "Enter the complete disk filename. ",OUTFILE$ 11240 OPEN OUTFILE$ FOR OUTPUT AS #1 11260 PRINT "Which of the ";PERIOD;"alphabets do you want to match?" 11280 PRINT 11300 INPUT " Enter number of 1st alphabet to be matched: ",ALF1 11320 INPUT " Enter number of 2nd alphabet to be matched: ",ALF2 11340 PRINT "MATCHING ALPHABET";ALF1;"AND ALPHABET";ALF2 11360 PRINT #1,"MATCHING ALPHABET";ALF1;"AND ALPHABET";ALF2 11380 FOR N=1 TO 26 11400 IF CMIXFLAG=1 THEN SET1(N)=PMIXFREQ(ALF1,N) ELSE SET1(N)=PFREQ(ALF1,N) 11420 IF CMIXFLAG=1 THEN SET2(N)=PMIXFREQ(ALF2,N) ELSE SET2(N)=PFREQ(ALF2,N) 11440 NEXT N 11460 FOR M=1 TO 26 11480 FOR L=1 TO 26 11500 PRINT #1," "MID$(CCOMPO$,L,1); ' Print first sequence 11520 NEXT L 11540 PRINT #1, 11560 FOR L=1 TO 26 11580 PRINT #1, USING "###";SET1(L); ' Print first sequence frequencies 11600 NEXT L 11620 PRINT #1, 11640 FOR L=0 TO 25 11660 LTRPOS=M+L :IF LTRPOS>26 THEN LTRPOS=LTRPOS-26 11680 PRINT #1, " ";MID$(CCOMPO$,LTRPOS,1); ' Print second sequence 11700 NEXT L 11720 PRINT #1, 11740 MATCH(M)=0 11760 FOR N=1 TO 26 11780 MATCH(M)=MATCH(M)+(SET1(N)*SET(N)) 11800 PRINT #1, USING "###";SET2(N); ' Print second sequence frequencies 11820 NEXT N 11840 PRINT #1, 11860 IF M/2-INT(M/2)<>0 THEN PRINT TAB(1) "MATCH";M;":";MATCH (M); ELSE PRINT TAB(40) "MATCH";M;":";MATCH (M): 11880 PRINT #1," MATCH";M;":";MATCH (M) :PRINT #1. 11900 SET2(27)=SET2(1) 11920 FOR N=1 TO 26 11940 SET2(N)=SET2(N+1): NEXT N 11960 NEXT M 11980 IF OUTFILE$=PRINTER$ THEN PRINT #1,FORMFEED$ 12000 INPUT "ANOTHER MATCH (Y/N)?",Q$ 12020 IF Q$="Y" OR Q$="y" THEN 11300 12040 IF OUTFILE$=PRINTER$ THEN PRINT #1,FORMFEED$ 12060 CLOSE #1 12080 RETURN
[End]