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.