To encode, it runs four polyalphabet passes, using the key string, then the key reversed, then the key plus extra increments, twice. Then it does a rail transpose. Decode is the inverse.
The input file can hold any ASCII characters from 0 to 255. The key can be any length, any ASCII char from 0 to 255.
The file length is padded for the rails, so that there are the same number of characters on each rail.
The number of rails is taken as the length of the key string.
If you put chr$( 0) as the key string, the first two passes should make no change. ( see first output example)
''--------------------------------------------------------------!!Command Line Initialisation!!--------------------------------------------------------''
Inputcmd$ = CommandLine$ '' Normal usage is from command line.
' Un-rem one of the next two lines for testing
Inputcmd$ = "commLineCyphDecyph.bas -e XYZZY plainText.txt encyph.txt" ' typical encyphering UN-REM one of these lines |
'Inputcmd$ = "commLineCyphDecyph.bas -d XYZZY encyph.txt decrypted.txt" ' typical decyphering UN-REM one of these lines |
'Inputcmd$ = "as h yh ary ay ts54 4us6z" ' unacceptable gobbledegook if no '-d' or '-e' in it.
print
print Inputcmd$
print
print " NB screen output, for debugging, shows ASCII control codes as '*'"
print " symbols and displays only first 80 chars while storing them all."
print
programname$ =word$( Inputcmd$, 1)
Choice$ =word$( Inputcmd$, 2)
key$ =word$( Inputcmd$, 3): key$ =chr$( 0) +chr$( 0) ' for testing
filename$ =word$( Inputcmd$, 4)
Fileoutput$ =word$( Inputcmd$, 5)
if not( instr( Inputcmd$, "-e")) and not( instr( Inputcmd$, "-d")) then print Inputcmd$: notice "GIGO!": end
i = len( key$)
do until i =0
keyChar$ =mid$( key$, i, 1) ''Generating the second key (reversed key)
key2$ =key2$ + keyChar$
i =i -1
loop
keyLength =len( key$) ''Key Length
Select case Choice$ ''Select Case to find choice
case "-d"
print " Decrypting"
goto [Decryption]
case "-e"
print " Encrypting"
goto [Encryption]
case else
goto [Quit]
end select
''--------------------------------------------------------------!!Encryption Section!!--------------------------------------------------------''
[Encryption] ''Opening the file using CL input
open filename$ for input as #inFile
plainText$ =input$( #inFile, lof( #inFile)) 'opening the file for input, put contents into string variable
close #inFile
print " Received plain text"
call safePrint plainText$
print " Key & reversed key ( control ASCII codes shown as '*'"
call safePrint ( key$ +" " +key2$)
print
''--------------------------------------------------------------!!Polyalphabetic Rounds!!--------------------------------------------------------''
index = 1 ''Resetting Index
for i =1 to len( plainText$) 'loop until end of PT
plainChar$ =mid$( plainText$, i, 1) 'Finding ASCII of character
plainCharNum =asc( plainChar$) 'Putting this into a variable
increment =asc( mid$( key$, index, 1)) 'Increment becomes the ascii value of key
cypherText$ =cypherText$ +chr$( ( plainCharNum +increment) mod 256) 'Incrementing one by the other
index =index +1 'Increasing the index
if index >keyLength then index =1 'Resetting the key according to length.
next i
print " first round"
call safePrint cypherText$
''ROUND TWO FIGHT!
index = 1 ''Resetting Index
for i =1 to len( cypherText$) 'loop until end of Cypher Text 1
plainChar$ =mid$( cypherText$, i, 1) 'Finding ASCII of character
plainCharNum =asc( plainChar$) 'Putting this into a variable
increment =asc( mid$( key2$, index, 1)) 'Increment becomes the ascii value of key
cypherText2$ =cypherText2$ +chr$( ( plainCharNum +increment) mod 256) 'Incrementing one by the other
index =index +1 'Increasing the index
if index >keyLength then index =1 'Resetting the key according to length.
next i
print " second round"
call safePrint cypherText2$
''ROUND THREE FIGHT
index = 1
for i =1 to len( cypherText2$) 'loop until end of cypherText2 !
plainChar$ =mid$( cypherText2$, i, 1) 'Finding ASCII of character
plainCharNum =asc( plainChar$) 'Putting this into a variable
increment =asc( mid$( key$, index, 1)) 'Increment becomes the ascii value of key
increment2 =increment + keyLength 'adding a further increment for another round.
cypherText3$ =cypherText3$ +chr$( ( plainCharNum + increment + increment2) mod 256) 'Incrementing one by the other
index =index +1 'Increasing the index
if index >keyLength then index =1 'Resetting the key according to length.
next i
print " third round"
call safePrint cypherText3$
''FINAL ROUND FIGHT
for i =1 to len( cypherText3$) 'loop until end of Cypher Text 1
plainChar$ =mid$( cypherText3$, i, 1) 'Finding ASCII of character
plainCharNum =asc( plainChar$) 'Putting this into a variable
increment =asc( mid$( key2$, index, 1)) 'Increment becomes the ascii value of key
increment2 =increment + keyLength 'Again adding another incrementation to the backward key
cypherText4$ =cypherText4$ +chr$( ( plainCharNum +increment+increment2) mod 256) 'Incrementing one by the other
index =index +1 'Increasing the index
if index >keyLength then index =1 'Resetting the key according to length.
next i
print " fourth round"
call safePrint cypherText4$
print
''--------------------------------------------------------------!!Rail Fence Cipher!!--------------------------------------------------------''
''Transposition Rail Cipher
transposeByN =keyLength ''use the key to give us the transposition number
LPT =len( cypherText4$) ''Length of the cypher text
pad =LPT mod transposeByN ''Finding the amount of "padding" needed to make the plaintext divisible by the keyLength
if pad <>0 then ' <<<<<<<< NB was calculating wrongly here ????
print "Padding by "; pad; " characters so length is raised from "; LPT; " to "; len( plainText$) +transposeByN -pad; " so now divisible by "; transposeByN
for i =1 to transposeByN -pad
cypherText4$ =cypherText4$ +"$" ''Adding the Pad
next i
end if
print " Padded text"
call safePrint cypherText4$ ''Print the cyphertext with the pad
print
dim part$( transposeByN) ''Creating array for the "parts" of the encrypted text
lenPT =len( cypherText4$)
for i =1 to lenPT +1 step transposeByN
for j =1 to transposeByN
part$( j) =part$( j) +mid$( cypherText4$, i +j -1, 1) ''Creating the rails to the cypher
next j
next i
print " Rail fence Transposition cyphered. Number of rails ="; transposeByN
for bin =1 to transposeByN
print " Rail "; bin
call safePrint part$( bin)
next bin
print
for bin =1 to transposeByN
cypherText5$ =cypherText5$ +part$( bin) ''Adding the rails together to create cyphertext
next bin
numRails$ = chr$( transposeByN) '<<<<<<< is this quite what you thought??? SHOULD BE chr$, (not str$ ).. one byte????
'<<<<<<<<<?????????
cypherText5$ = cypherText5$ + numRails$ ''appending the number of rail barss to the file, ie last byte holds number of bars of the rail.
''--------------------------------------------------------------!!Writing the cypher text to file!!--------------------------------------------------------''
open Fileoutput$ for output as #MyOutput
#MyOutput, cypherText5$;
close #MyOutput
print " Encrypted text is"
call safePrint cypherText5$ '<<<<<< you had 3 here????
goto [Quit]
''--------------------------------------------------------------!!Decryption!!--------------------------------------------------------''
[Decryption]
open filename$ for input as #inFile
cypherText5$ =input$( #inFile, lof( #inFile)) 'opening the file for input
close #inFile
''--------------------------------------------------------------!!Rail Fence Recovery!!--------------------------------------------------------''
numRails =asc( right$( cypherText5$, 1)) ''Grabbing the rails number ' <<<<<<< asc not val??????
lenCypher =len( cypherText5$) -1 ' <<<<<<< since held in one byte
cypherText4$ =left$( cypherText5$, lenCypher)
transposeByN =keyLength ' there are transposeByN rails, each of length fractLength
fractLength =int( lenCypher /numRails) ' ????
print " Whole length "; lenCypher; " "; "Section length "; fractLength; " repeated "; numRails; " times."
print " File to decrypt"
call safePrint cypherText5$
print
for i =0 to fractLength -1
for j =0 to numRails -1
recover$ =recover$ +mid$( cypherText5$, 1 +i +j *fractLength, 1)
next j
next i
cypherText4$ =recover$
print
print " Text Recovery"
print " 4"
call safePrint cypherText4$
''--------------------------------------------------------------!!Polyalphabetic round recovery!!--------------------------------------------------------''
index = 1
for i =1 to len( cypherText4$)
recoveredChar$ =mid$( cypherText4$, i, 1)
recoveredCharNum =asc( recoveredChar$)
decrement =( asc( mid$( key2$, index, 1)))
decrement2 =decrement + keyLength
pointer =recoveredCharNum -decrement - decrement2
if pointer <0 then pointer =pointer +256
cypherText3$ =cypherText3$ +chr$( pointer)
index =index +1
if index >keyLength then index =1
next i
print " 3"
call safePrint cypherText3$
index = 1
for i =1 to len( cypherText3$)
recoveredChar$ =mid$( cypherText3$, i, 1)
recoveredCharNum =asc( recoveredChar$)
decrement =( asc( mid$( key$, index, 1)))
decrement2 =decrement + keyLength
pointer =recoveredCharNum -decrement - decrement2
if pointer <0 then pointer =pointer +256
cypherText2$ =cypherText2$ +chr$( pointer)
index =index +1
if index >keyLength then index =1
next i
print " 2"
call safePrint cypherText2$
index = 1
for i =1 to len( cypherText2$)
recoveredChar$ =mid$( cypherText2$, i, 1)
recoveredCharNum =asc( recoveredChar$)
decrement =( asc( mid$( key2$, index, 1)))
pointer =recoveredCharNum -decrement
if pointer <0 then pointer =pointer +256
cypherText$ =cypherText$ +chr$( pointer)
index =index +1
if index >keyLength then index =1
next i
print " 1"
call safePrint cypherText$
index = 1
for i =1 to len( cypherText$)
recoveredChar$ =mid$( cypherText$, i, 1)
recoveredCharNum =asc( recoveredChar$)
decrement =( asc( mid$( key$, index, 1)))
pointer =recoveredCharNum -decrement
if pointer <0 then pointer =pointer +256
recoveredText$ =recoveredText$ +chr$( pointer)
index =index +1
if index >keyLength then index =1
next i
print
print " Recovered text is"
print recoveredText$ ' No need for safe print since will be ASCII above 31, printable...
open Fileoutput$ for output as #MyOutput
#MyOutput, recoveredText$;
close #MyOutput
''--------------------------------------------------------------!!End of Program!!--------------------------------------------------------''
[Quit]
print
print " Exiting."
end
' _______________________________________________________________________
sub safePrint in$
for i =1 to len( in$)
c$ =mid$( in$, i, 1)
if asc( c$) >31 then print c$; else print "*";
if i >80 then print "....etc..etc..": exit for
next i
print
end sub
' _______________________________________________________________________
NB The first two passes therefore do nothing. The next two just shift all characters by the same amount through the alphabet of ASCII chars.
Encrypting
Received plain text
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
Key & reversed key ( control ASCII codes shown as '*'
** **
first round
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
second round
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
third round
CDEFGHIJKLMNOPQRSTUVWXYZ[\cdefghijklmnopqrstuvwxyz{|"23456789:;**Vjku"ku"vjg"rnck....etc..etc..
fourth round
EFGHIJKLMNOPQRSTUVWXYZ[\]^efghijklmnopqrstuvwxyz{|}~$456789:;<=**Xlmw$mw$xli$tpem....etc..etc..
Padded text
EFGHIJKLMNOPQRSTUVWXYZ[\]^efghijklmnopqrstuvwxyz{|}~$456789:;<=**Xlmw$mw$xli$tpem....etc..etc..
Rail fence Transposition cyphered. Number of rails =2
Rail 1
EGIKMOQSUWY[]egikmoqsuwy{}$579;=*lwm$l$pm$ix*Xm$wxiterx|2*lwm$l$pm$ix*Xm$wxiterx|....etc..etc..
Rail 2
FHJLNPRTVXZ\^fhjlnprtvxz|~468:<*Xm$wxiterx|2*lwm$l$pm$ix*Xm$wxiterx|2*lwm$l$pm$ix....etc..etc..
Encrypted text is
EGIKMOQSUWY[]egikmoqsuwy{}$579;=*lwm$l$pm$ix*Xm$wxiterx|2*lwm$l$pm$ix*Xm$wxiterx|....etc..etc..
Exiting.
Decrypting
Whole length 340 Section length 170 repeated 2 times.
File to decrypt
EGIKMOQSUWY[]egikmoqsuwy{}$579;=*lwm$l$pm$ix*Xm$wxiterx|2*lwm$l$pm$ix*Xm$wxiterx|....etc..etc..
Text Recovery
4
EFGHIJKLMNOPQRSTUVWXYZ[\]^efghijklmnopqrstuvwxyz{|}~$456789:;<=**Xlmw$mw$xli$tpem....etc..etc..
3
CDEFGHIJKLMNOPQRSTUVWXYZ[\cdefghijklmnopqrstuvwxyz{|"23456789:;**Vjku"ku"vjg"rnck....etc..etc..
2
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
1
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
Recovered text is
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
Exiting.
commLineCyphDecyph.bas -e XYZZY plainText.txt encyph.txt
NB screen output, for debugging, shows ASCII control codes as '*'
symbols and displays only first 80 chars while storing them all.
Encrypting
Received plain text
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789**This is the plai....etc..etc..
Key & reversed key ( control ASCII codes shown as '*'
XYZZY YZZYX
first round
™›žžž ¢£££¥§¨¨¨ª¬¯±²²²º¼½½½¿ÁÂÂÂÄÆÇÇÇÉËÌÌÌÎÐÑÑÑÓzŠŠŠŒŽ‘“gc¬ÁÃÍyÁÌzÎÁ½yÊÆºÁ....etc..etc..
second round
òõ÷÷ö÷úüüûüÿ************************* * #%%$%(**)*-ÔãâãæèèçèëíÀ»***&Ñ*&Ô'**Ó$***....etc..etc..
third round
§¬°°¬±µµ²±¶ºº·¶»¿¿¼»ÀÄÄÁÀËÏÏÌËÐÔÔÑÐÕÙÙÖÕÚÞÞÛÚßããàß䜙˜¡¡ž¢¦yrºÒÖ߈ÏÝàÐËŠÝØÉÏ....etc..etc..
fourth round
^eigbcjnlghosqlmtxvqry}{vw„ˆ†‚‰‹†‡Ž’‹Œ“—•‘˜œš•–FSNOVZXST[_0'q‹–=†–F—…‚C–~†....etc..etc..
Padded text
^eigbcjnlghosqlmtxvqry}{vw„ˆ†‚‰‹†‡Ž’‹Œ“—•‘˜œš•–FSNOVZXST[_0'q‹–=†–F—…‚C–~†....etc..etc..
Rail fence Transposition cyphered. Number of rails =5
Rail 1
^chmrw‚‡Œ‘–OTq†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•
Rail 2
ejoty„‰Ž“˜V[‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—‹–C‘—
Rail 3
insx}ˆ’—œFZ_F–FTF–FTF–FTF–FTF–FTF–FTF–FTF–FTF–FTF–FTF–FT
Rail 4
glqv{†‹•šSX0–——0–——0–——0–——0–——0–——0–——0–——0–——0–——0–——0
Rail 5
bglqv†‹•NS'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'=…~‚'
Encrypted text is
^chmrw‚‡Œ‘–OTq†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•ejoty„‰Ž“˜V[....etc..etc..
Exiting.
commLineCyphDecyph.bas -d XYZZY encyph.txt decrypted.txt
NB screen output, for debugging, shows ASCII control codes as '*'
symbols and displays only first 80 chars while storing them all.
Decrypting
Whole length 340 Section length 68 repeated 5 times.
File to decrypt
^chmrw‚‡Œ‘–OTq†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•q†‚†•ejoty„‰Ž“˜V[....etc..etc..
Text Recovery
4
^eigbcjnlghosqlmtxvqry}{vw„ˆ†‚‰‹†‡Ž’‹Œ“—•‘˜œš•–FSNOVZXST[_0'q‹–=†–F—…‚C–~†....etc..etc..
3
§¬°°¬±µµ²±¶ºº·¶»¿¿¼»ÀÄÄÁÀËÏÏÌËÐÔÔÑÐÕÙÙÖÕÚÞÞÛÚßããàß䜙˜¡¡ž¢¦yrºÒÖ߈ÏÝàÐËŠÝØÉÏ....etc..etc..
2
òõ÷÷ö÷úüüûüÿ************************* * #%%$%(**)*-ÔãâãæèèçèëíÀ»***&Ñ*&Ô'**Ó$***....etc..etc..
1
™›žžž ¢£££¥§¨¨¨ª¬¯±²²²º¼½½½¿ÁÂÂÂÄÆÇÇÇÉËÌÌÌÎÐÑÑÑÓzŠŠŠŒŽ‘“gc¬ÁÃÍyÁÌzÎÁ½yÊÆºÁ....etc..etc..
Recovered text is
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
This is the plain text.
Exiting.