text: import sys, cryptomath, random
  
  #SYMBOLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?.'
  SYMBOLS = ''.join(chr(i) for i in range(32,127))
  
  def main():
      #myMessage = """"A computer would deserve to be called intelligent if it could deceive a human into believing that it was human." -Alan Turing"""
      #myKey = 2894
      #myMode = 'encrypt' # Set to either 'encrypt' or 'decrypt'.
  
      myMessage = raw_input('\nEnter message: ')
      myKey = int(raw_input("Encryption/decryption key: "))
      #myKey = getRandomKey()
      myMode = raw_input("Would you like to \"encrypt\" or \"decrypt\" this message? ")
  
      if myMode == 'encrypt':
          translated = encryptMessage(myKey, myMessage)
      elif myMode == 'decrypt':
          translated = decryptMessage(myKey, myMessage)
      else:
          print "\nImproper mode detected! Exiting.\n"
          sys.exit()
   
      print 'Key: %s' % (myKey)
      print '\n%sed text:' % (myMode.title())
      print translated
      print '\n'
  
  def getKeyParts(key):
      keyA = key // len(SYMBOLS)
      keyB = key % len(SYMBOLS)
      return (keyA, keyB)
  
  def checkKeys(keyA, keyB, mode):
      if keyA == 1 and mode == 'encrypt':
          sys.exit('Cipher is weak if key A is 1. Choose a different key.')
      if keyB == 0 and mode == 'encrypt':
          sys.exit('Cipher is weak if key B is 0. Choose a different key.')
      if keyA < 0 or keyB < 0 or keyB > len(SYMBOLS) - 1:
          sys.exit('Key A must be greater than 0 and Key B must be between 0 and %s.' % (len(SYMBOLS) - 1))
      if cryptomath.gcd(keyA, len(SYMBOLS)) != 1:
          sys.exit('Key A (%s) and the symbol set size (%s) are not relatively prime. Choose a different key.' % (keyA, len(SYMBOLS)))
  
  def encryptMessage(key, message):
      keyA, keyB = getKeyParts(key)
      checkKeys(keyA, keyB, 'encrypt')
      ciphertext = ''
      for symbol in message:
          if symbol in SYMBOLS:
              # Encrypt the symbol:
              symbolIndex = SYMBOLS.find(symbol)
              ciphertext += SYMBOLS[(symbolIndex * keyA + keyB) % len(SYMBOLS)]
          else:
              ciphertext += symbol # Append the symbol without encrypting.
      return ciphertext
  
  def decryptMessage(key, message):
      keyA, keyB = getKeyParts(key)
      checkKeys(keyA, keyB, 'decrypt')
      plaintext = ''
      modInverseOfKeyA = cryptomath.findModInverse(keyA, len(SYMBOLS))
  
      for symbol in message:
          if symbol in SYMBOLS:
              # Decrypt the symbol:
              symbolIndex = SYMBOLS.find(symbol)
              plaintext += SYMBOLS[(symbolIndex - keyB) * modInverseOfKeyA % len(SYMBOLS)]
          else:
              plaintext += symbol # Append the symbol without decrypting.
      return plaintext
  
  def getRandomKey():
      while True:
          keyA = random.randint(2, len(SYMBOLS))
          keyB = random.randint(2, len(SYMBOLS))
          if cryptomath.gcd(keyA, len(SYMBOLS)) == 1:
              return keyA * len(SYMBOLS) + keyB
  
  if __name__ == '__main__':
      main()
  