Implementing an encryption standard over message text
Functions are your friend. The remove repeated code and improve readability. I have absolutely no idea what the block of text does inside the "".join(XXXX) calls. There is too much going on there that I'm not going to take the time to see what it does or if it can be done better.

However, it does appear that you can replace that mess with something like this:

def doA():
  pass
def doB():
  pass
def makeJoinArgument(value, which_step,step1, step2):
  return step1() if (which_step) else step2() for x in value
def encode(value):
  return "".join("abc", True, doA, doB)
def decode(value):
  return "".join("abc", True, doB, doA)


This obviously doesn't run (and not exactly what you have), but it is much more manageable than what you have now.

Another note (from PEP 8: Style Guide)


  Always use a def statement instead of an assignment statement that
  binds a lambda expression directly to a name.
  
  Yes:
  
  def f(x): return 2*x
  
  No:
  
  f = lambda x: 2*x
  
  The first form means that the name of the resulting function object is
  specifically 'f' instead of the generic ''. This is more
  useful for tracebacks and string representations in general. The use
  of the assignment statement eliminates the sole benefit a lambda
  expression can offer over an explicit def statement (i.e. that it can
  be embedded inside a larger expression)