JDpaste

Vigenere cipher

Sep 23rd, 2021 (edited)
499
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.42 KB | None | 0 0
  1. # implement Vigenere cipher.
  2. # or : pip install pycipher .. from pycipher import Vigenere .. Vigenere('SECRETKEY').encipher('defend at all costs')
  3.  
  4. ordA = ord('A')   #  65 ( or x41 ) ASCII / Unicode codepoint
  5. #-- -----------------  
  6. def getVigenereSquare():
  7.     """ build a Vigenere Square. Return a "list of lists"  mapped to a tuple of Strings """    
  8.     vSquare = []
  9.     for row in range( 26 ):
  10.         # add row of letters as a String ..
  11.         thisRow = []
  12.         for col in range( 26 ):
  13.             #
  14.             # (col + row) % 26
  15.             charOffset = col + row      # in 0..50
  16.             if charOffset >= 26 : charOffset -= 26     # now in 0..25  ie. < 26
  17.             #
  18.             thisRow.append( chr( ordA + charOffset ) ) # set char value in 'cell'
  19.         #
  20.         # vSquare.append( tuple( thisRow ) ) # read-only .. or ..
  21.         vSquare.append( "".join( thisRow ) ) # read-only String
  22.     #
  23.     return tuple( vSquare ) # read-only seq of Strings
  24. #------------------------
  25.  
  26. #==========================
  27. vSquare = getVigenereSquare() # use as a GLOBAL.   read-only
  28. #==========================
  29. #DEBUG: show SQUARE ..
  30. for row in range( 26 ): print( vSquare[row] )
  31. print('>')
  32.  
  33. #-- ------------------
  34. def getIndexListForKey( key ):
  35.     """ sanitise the key, then map to list of indexes """
  36.     key = key.upper()
  37.     keyIter = filter( filterUPPER, key ) # strip out all non-UPPER
  38.     #
  39.     #keyIndices = []
  40.     #for c in keyIter: # pull each char from filter iterator ..
  41.     #    keyIndices.append( ord( c ) - ordA ) # map 'A'..'Z' --> 0..25
  42.     #
  43.     # demo .. instead use a list comprehension
  44.     keyIndices = [ ord( c ) - ordA for c in keyIter ] # map 'A'..'Z' --> 0..25
  45.     return tuple( keyIndices ) # read-only
  46. #---------------------------
  47. def filterUPPER( s="" ):  # utility
  48.     """ filter function UPPERCASE only """
  49.     return s.isupper()
  50. #-------------------
  51.  
  52. #-- ===============
  53. def encryptVigenere( key="", plainTxt="" ):
  54.     """ encrypt Vigenere """
  55.     # vSquare = getVigenereSquare()  # now made Global
  56.  
  57.     keyIndices = getIndexListForKey( key )
  58.     print('\nKey:', key, ':> produced indices:', keyIndices ) # DEBUG .. REMOVE !!!
  59.    
  60.     keyIndexLimit = len( keyIndices )
  61.     keyIndex = 0
  62.  
  63.     if keyIndexLimit == 0 or len(plainTxt) == 0 : return "" # empty !?!
  64.    
  65.     # build list of chars using append
  66.     cipherChars = []
  67.    
  68.     for thisToken in plainTxt :
  69.         if thisToken.isalpha() :
  70.             #
  71.             tokenUPPER = thisToken.upper()
  72.             #
  73.             thisRow  = vSquare[ ord( tokenUPPER ) - ordA ]
  74.             thisChar = thisRow[ keyIndices[ keyIndex ] ]
  75.             #
  76.             keyIndex += 1
  77.             if keyIndex >= keyIndexLimit : keyIndex = 0  # wrap
  78.         #
  79.         else:
  80.             thisChar = thisToken  # pass through
  81.         #
  82.         cipherChars.append( thisChar )
  83.     #
  84.     cipherTxt = "".join( cipherChars )
  85.     print( plainTxt )  # DEBUG .. REMOVE !!!
  86.     return cipherTxt
  87. #   ------ ---------
  88.  
  89. def decryptVigenere( key="", cipherTxt="" ):
  90.     """ decrypt Vigenere """
  91.     # vSquare = getVigenereSquare()  # now made Global
  92.  
  93.     keyIndices = getIndexListForKey( key )    
  94.     print('\nKey:', key, ':> produced indices:', keyIndices ) # DEBUG .. REMOVE !!!
  95.    
  96.     keyIndexLimit = len( keyIndices )
  97.  
  98.     if keyIndexLimit == 0 or len(cipherTxt) == 0 : return "" # empty !?!
  99.    
  100.     # build list of chars using append
  101.     keyIndex   = 0
  102.     plainChars = []
  103.    
  104.     for thisToken in cipherTxt :
  105.         if thisToken.isalpha():
  106.             #
  107.             thisRow  = vSquare[ keyIndices[ keyIndex ] ]
  108.             keyIndex += 1
  109.             if keyIndex >= keyIndexLimit : keyIndex = 0  # wrap
  110.             #
  111.             searchChar = thisToken.upper()
  112.             #
  113.             colIndex = thisRow.index( searchChar )
  114.             thisChar = chr( ordA + colIndex )
  115.         else:
  116.             thisChar = thisToken  # pass through
  117.         #
  118.         plainChars.append( thisChar )
  119.     #
  120.     plainTxt = "".join( plainChars )
  121.     print( cipherTxt )  # DEBUG .. REMOVE !!!
  122.     return plainTxt
  123. #   ------ --------
  124.  
  125. #----------- **************************************************************************************************
  126. # TEST calls ..
  127. print("\n... DECRYPTING ...")
  128. result = decryptVigenere('polyalphabetic','Lvlr yppy wbw mpg Kwrcnpgl cjtamt uwyylwn jrbgdmf, tbognr xa’s sibop pg efe fcirfedidas ngpsty?')
  129. print( result )
  130. #
  131. result = decryptVigenere('RPI','z pu vckinxkxvx p uvharvm')
  132. print( result )
  133. #
  134. result = decryptVigenere('R','z rd vetipgkzex r dvjjrxv')
  135. print( result )
  136. # RPI hello
  137. result = decryptVigenere('RPI','yttcd')
  138. print( result )
  139. #
  140. result = decryptVigenere('polyalphabetic','xh hys nghcliw qp twrftptu fjjmg hdic')
  141. print( result )
  142.  
  143. print("\n... ENCRYPTING ...")
  144. # RPI hello yttcd
  145. result = encryptVigenere('RPI','hello')
  146. print( result )
  147. #
  148. result = encryptVigenere('RPI','I am encrypting a message')
  149. print( result )
  150. #
  151. result = encryptVigenere('polyalphabetic','I am encrypting a message')
  152. print( result )
  153. #
  154. result = encryptVigenere('a key with spaces and digits 123', 'Non alpha chars are filtered out from key phrase')
  155. print( result )
  156. #
  157.  
  158. print("\n... DECRYPTING AGAIN...")
  159. result = decryptVigenere('a key with spaces and digits 123','NYR YHXAH UWATW SRR ILTZMKWD YYR BZHT CTY RLJAFH')
  160. print( result )
  161. #
  162. result = decryptVigenere('polyalphabetic','xb pggsileo jbnvn tzsr ti dat gkiezso')
  163. print( result )
  164. #
  165.  
Add Comment
Please, Sign In to add comment