# stores functions for a module in a password manager

def encode(m):
   """
   Encodes the string in m as a long integer
   where every character in m takes 3 digits.
   """
   L = [ord(c) for c in m]
   S = ["%03d" % i for i in L]
   R = reduce(lambda x,y: x+y,S)
   n = int(R)
   return n

def decode(n):
   """
   Decodes the integer n into a string where
   every 3 digits in n represent a character.
   """
   a = str(n)
   L = [a[3*i:3*i+3] for i in range(0,len(a)/3)]
   S = [chr(int(c)) for c in L]
   m = reduce(lambda x,y: x+y,S)
   return m

def modexp(n,k,m):
   """
   Modular exponentiation of n with key k, mod m.
   """
   result = 0; work = n; shift = 1
   while (work > 0):
      rest = work % m 
      result = result + ((rest**k) % m)*shift
      work = (work - rest)/m
      shift = shift*m
   return result;

def encrypt(s,e,m):
   """
   Encrypts the string using the encryption key e
   and modulus m.  Returns the encrypted number.
   """
   n = encode(s)
   return modexp(n,e,m)

def decrypt(n,k,m):
   """
   Decrypts the string using key k, mod m.
   Returns the decrypted number as a string.
   """
   d = modexp(n,k,m)
   return decode(d)

def test():
   """
   Runs some basic tests on the functions.
   """
   m = raw_input("give a message : ")
   c = encode(m)
   print "\"%s\" is encoded as \"%s\"" % (m,c)
   d = decode(c)
   print "\"%s\" is decoded as \"%s\"" % (c,d)
   p = 5; q = 11; n = p*q; e = 27; k = 3
   enc_m = encrypt(m,e,n)
   A = "\"%s\" is encrypted as \"%s\"" % (m,enc_m)
   print A
   M = decrypt(enc_m,k,n)
   B = "\"%s\" is decrypted as \"%s\"" % (enc_m,M)
   print B

if __name__ == "__main__": test()
