JDpaste

Monoalphabetic substitution cipher + Caesar

Oct 4th, 2021 (edited)
599
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.98 KB | None | 0 0
  1. """JD cipher module"""
  2. #-- -----------
  3. def getAlphabet( shift = 0 ):
  4.     """Return: eg. (shift == 1) -> 'BCDEFGHIJKLMNOPQRSTUVWXYZA' """
  5.     ordA = ord('A')                 # ord() gets codepoint for Unicode char
  6.    
  7.     if ( isinstance( shift, int )) : # int, so shift ..
  8.         if ( shift < 0 ): shift = 0 # .. guard
  9.         # build letter sequence as a String ..
  10.         return "".join([ chr( ordA + ( i + shift ) % 26 ) for i in range( 26 )])
  11.     #
  12.     return ""
  13. #
  14. #-- -----------------
  15. def getVigenereSquare():
  16.     """ build a Vigenere Square. Return a "list of strings"  mapped to a tuple of Strings """    
  17.     #
  18.     return tuple( [ getAlphabet(s) for s in range( 26 ) ])   # read-only: seq of 26 Strings
  19. #----------------
  20.  
  21. #==========================
  22. vSquare = getVigenereSquare() # use as a GLOBAL.   read-only
  23. #==========================
  24. #DEBUG: show SQUARE ..
  25. print('\n"Vigenère square" follows ...\n')
  26. for row in range( 26 ): print( vSquare[row] )
  27. print('>')
  28.  
  29. #-- ---------
  30. def encCaesar( key = 0, plainText = "" ):
  31.     """ Caesar cipher is sometimes called a shift cipher. Encipher given plaintext."""
  32.     #
  33.     thisAlphabet = vSquare[key] # OR getAlphabet( key )
  34.  
  35.     return encMonoSub( thisAlphabet, plainText ) # use the monoalphabetic substitution cipher
  36. #
  37. #-- ---------
  38. def decCaesar( key = 0, cipherText = "" ):
  39.     """ Caesar cipher is sometimes called a shift cipher. Decipher given ciphertext."""
  40.     #
  41.     standardAlphabet = vSquare[0] # OR getAlphabet(0)
  42.    
  43.     # I discovered that DECRYPTING the "standard alphabet" with ..
  44.     # .. a 'mono alphabet' yields the "reciprocal (inverse decrypt) alphabet"
  45.    
  46.     thisAlphabet = decMonoSub( vSquare[key], standardAlphabet )  # OR getAlphabet( key )
  47.  
  48.     return encMonoSub( thisAlphabet, cipherText ) # use the monoalphabetic substitution cipher
  49. #
  50. #-- -----------------
  51. def caesarEncipherALLkeys( plainText = "" ):  # NOT USED .. demos shift alg.
  52.     """ Caesar cipher is sometimes called a shift cipher. Encipher given plaintext."""
  53.     print( '>> ' + plainText )      # DEBUG output
  54.     ordZ = ord('Z')                 # ord() gets codepoint for Unicode char
  55.     plainText = plainText.upper()
  56.     # assume UPPERCASE or <space ' '>
  57.     for k in range( 1, 26 ) :
  58.         cipherText = ''
  59.         for token in plainText :
  60.             if token == ' ':   # space chars pass thru ..
  61.                 cypherChar = ' '
  62.             else:              # map char using shift ..
  63.                 cypherOrd = ord( token ) + k
  64.                 if cypherOrd > ordZ : cypherOrd -= 26
  65.                
  66.                 cypherChar = chr( cypherOrd )
  67.             #
  68.             cipherText += cypherChar  # append each char to build 'cyphertext'
  69.         #
  70.        
  71.         # DEBUG: show result for each key in 1..25
  72.         if k <= 9 :
  73.             key = ' ' + str(k) # space pad for single digit .. pretty print !
  74.         else:
  75.             key = str(k)
  76.         #
  77.         outTxt = key +' '+ cipherText
  78.         print( outTxt )
  79.     #
  80. #
  81. #----------------------------------------------------------------------------------------------------------
  82. def encMonoSub( alphabet="", txt=""):
  83.     """A monoalphabetic substitution cipher uses a fixed system of substitution
  84. in that a letter in the plaintext is always replaced by the same letter or symbol to create the ciphertext.
  85. Handles non-linear substitution."""
  86.    
  87.     lenTxt = len(txt)
  88.     if ( lenTxt == 0 or len(alphabet) != 26 ) : return "ERROR: "+ str( len( alphabet ))
  89.     #    -----------    -------------------     ----------------
  90.     ordA = ord('A')         # ord() gets codepoint for Unicode char
  91.     plainText = txt.upper()
  92.     cipherChars = []
  93.     for token in plainText :
  94.         if token.isupper():     # map char using alphabet
  95.             cypherChar = alphabet[ ord( token ) - ordA ]        # LOOK-UP
  96.         #
  97.         else:   # other chars pass thru ..
  98.             cypherChar = token
  99.         #
  100.         cipherChars.append( cypherChar )
  101.     #
  102.     return "".join( cipherChars )  # a String
  103. #
  104. #-- ----------
  105. def decMonoSub( alphabet="", txt=""):
  106.     """A monoalphabetic substitution cipher uses a fixed system of substitution
  107. in that a letter in the plaintext is always replaced by the same letter or symbol to create the ciphertext.
  108. Handles non-linear substitution."""
  109.    
  110.     # I discovered that DECRYPTING the "standard alphabet" with ..
  111.     # .. a 'mono alphabet' yields the "reciprocal (inverse decrypt) alphabet"
  112.    
  113.     lenTxt = len(txt)
  114.     if ( lenTxt == 0 or len(alphabet) != 26 ) : return "ERROR "+ str( len( alphabet ))
  115.     #    -----------    -------------------     ----------------
  116.     ordA = ord('A')         # ord() gets codepoint for Unicode char
  117.     cipherText = txt.upper()
  118.     plainChars = []
  119.     for token in cipherText :
  120.         if token.isupper():     # map char using alphabet
  121.             plainChar = chr( ordA + alphabet.index( token ))   #SEARCH using .. index( token )
  122.         else:   # other chars pass thru ..
  123.             plainChar = token
  124.         #
  125.         plainChars.append( plainChar )
  126.     #
  127.     return "".join( plainChars )  # a String
  128. #
  129. #-- -------------
  130. def showALLshifts( cipherText = "" ):
  131.     #
  132.     print( '\n>> ' + cipherText )     # DEBUG output
  133.     ordA = ord('A')                 # ord() gets codepoint for Unicode char
  134.     cipherText = cipherText.upper() # force UPPERCASE ascii
  135.     #
  136.     for k in range( 1, 26 ) : #  in 1..25
  137.         #
  138.         plainTxt = decCaesar( k, cipherText )
  139.         #          =========
  140.        
  141.         # show result for each key in 1..25
  142.         if k <= 9 :
  143.             key = ' ' + str(k) # space pad for single digit .. pretty print !
  144.         else:
  145.             key = str(k)
  146.         #
  147.         print( key, plainTxt )
  148.     #
  149. #
  150. #----------------------------------------------------------------------------------------------------------
  151. # TEST calls ..
  152. #--------------------
  153. print( '\n*** ENCIPHER MonoSub on "ABCDEFGHIJKLMNOPQRSTUVWXYZ" returns the KEY alphabet ! ***' )
  154. result = encMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  155. print( result ) # -> scramble alphabet
  156.  
  157. print( '\n*** DECIPHER MonoSub on "ABCDEFGHIJKLMNOPQRSTUVWXYZ" returns the related reciprocal (inverse) alphabet !!! ***' )
  158. result = decMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  159. print( result ) # -> related unscramble (inverse) alphabet !!!
  160.  
  161. print( '\n*** Show the alphabet and its inverse for Caesar (2) ***' )
  162. print( encMonoSub( getAlphabet( 2 ), getAlphabet() ))
  163. print( decMonoSub( getAlphabet( 2 ), getAlphabet() ))
  164.  
  165. print( '\n*** ENCIPHER MonoSub ***' )
  166. result = encMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'AL-KINDI WAS BORN IN YEMEN TO A RICH FAMILY AS WELL AS PHILOSOPHY, HE WORKED IN ASTRONOMY, ALCHEMY, MATHEMATICS, MEDICINE, GEOGRAPHY, AND MANY OTHER TOPICS. HE BECAME A MEMBER OF A SCIENTIFIC PLACE OF STUDY CALLED THE HOUSE OF WISDOM. HIS TREATISES ON MUSIC WERE THOUGHT TO BE THE BEST WORKS ON THE SUBJECT OF MUSIC IN ARABIC.')
  167. print( result )
  168. print( '\n*** DECIPHER using ENCIPHER MonoSub with "inverse alphabet" ***' )
  169. result = encMonoSub("FKVAWDMNJHQBSTEGPCLROIXZYU", 'DS-BVHFV EDM LUTH VH YOGOH NU D TVRJ ADGVSY DM EOSS DM QJVSUMUQJY, JO EUTBOF VH DMNTUHUGY, DSRJOGY, GDNJOGDNVRM, GOFVRVHO, POUPTDQJY, DHF GDHY UNJOT NUQVRM. JO LORDGO D GOGLOT UA D MRVOHNVAVR QSDRO UA MNZFY RDSSOF NJO JUZMO UA EVMFUG. JVM NTODNVMOM UH GZMVR EOTO NJUZPJN NU LO NJO LOMN EUTBM UH NJO MZLIORN UA GZMVR VH DTDLVR.')
  170. print( result )
  171.  
  172. print( '\n*** DECIPHER ... ***' )
  173. result = decMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'JV. GY HDGO VM GDNNJOE.')
  174. print( result )
  175.  
  176. print( '\n*** ENCIPHER MonoSub: HI MY NAME IS MILLIE ***' )
  177. result = encMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'HI MY NAME IS MILLIE')
  178. print( result )
  179.  
  180. print( '\n*** DECIPHER "jv gy hdgo vm gvssvd" using ENCIPHER MonoSub with "inverse alphabet"  ***' )
  181. result = encMonoSub("FKVAWDMNJHQBSTEGPCLROIXZYU", 'jv gy hdgo vm gvssvd')
  182. print( result )
  183.  
  184. print( '\n*** DECIPHER using ENCIPHER MonoSub with "inverse alphabet" ***' )
  185. result = encMonoSub("FKVAWDMNJHQBSTEGPCLROIXZYU", 'qsodmzto goonvhp yuz')
  186. print( result )
  187.  
  188. print( '\n*** DECIPHER MonoSub using DECRYPT ALGORITHM ***' )
  189. result = decMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'qsodmzto goonvhp yuz')
  190. print( result )
  191.  
  192. print( '\n*** ENCIPHER MonoSub ***' )
  193. result = encMonoSub("DLRFOAPJVIBSGHUQKTMNZCEWYX", 'John Davis')
  194. print( result )
  195. #--- Caesar ...  -----------------------
  196. print( '\n*** Caesar examples .. ***' )
  197. print( decCaesar( 5, 'WJYZWS YT WTRJ') ) # .. RETURN TO ROME
  198. print( encCaesar( 7, 'IF YOU CAN GUESS THE KEY IT IS EASY TO DECRYPT THE MESSAGE.'))
  199. print( decCaesar( 7, 'PM FVB JHU NBLZZ AOL RLF PA PZ LHZF AV KLJYFWA AOL TLZZHNL.'))
  200.  
  201. showALLshifts('PM FVB JHU NBLZZ AOL RLF PA PZ LHZF AV KLJYFWA AOL TLZZHNL.')
  202. showALLshifts('IF YOU CAN GUESS THE KEY IT IS EASY TO DECRYPT THE MESSAGE.')
  203. #
  204. print( "----")
  205. print( decCaesar( 17, 'z rd vetipgkzex r dvjjrxv'))
  206. print( decCaesar( 15, 'htatri iwt utaxct'))
  207. print( decCaesar(  1, 'xfmdpnfcbdl'))
  208. print( decCaesar( 25, 'khjdvhrd'))
  209.  
Add Comment
Please, Sign In to add comment