SouthParkMe

Hi.

This site tends to hold geeky things.

Playfair Python Code

Playfair Python Code

The other day, I posted a description of the playfair cipher. Here is some code that encrypts and decrypts this cipher.

# This code will generate the playfair cipher and encode or decode some text

def letteronly(text):
    """
    This does some sanitising - only letters make it through
    """
    output=''
    for char in text:
        if 64 < ord(char) < 91:
            if char=='J':
                char='I'
            output+=char
    return(output)


def massageKey(txt):
    """ 
    This turns the key into a 25 letter grid albeit one
    that has been expressed linearly
    """
    userkey=letteronly(txt)
    key=''
    for char in userkey:
        if char not in key:
            key+=char
    return(key)

def massageMessage(txt):
    """
    Break the message into digraphs, repeated letters have an X
    I cannot use just the placing in original string as earlier digraph
    will upset things

    i.e. HELLO becomes HE LX LO

    and ALLOWS is AL LO W
    """
    usrmsg=letteronly(txt)
    msg=''
    # keep track of where we are in diagraph 
    First=True
    for i in range(len(usrmsg)):

        # I am on the first letter in a digraph
        if First:
            msg+=usrmsg[i]

            # if last letter of message, append X
            # the plus 1 is as i counts from zero, len does not
            if i + 1 == len(usrmsg):
                msg+='X'
            
            # if next letter is the same, append X
            # or go onto second letter
            else:
                if usrmsg[i] == usrmsg[i+1]:
                    msg+='X'
                else:
                    First=False
        else:
            # just append second letter
            msg+=usrmsg[i]
            First=True
    return(msg)

def showgrid(key):
    """
    Show the key grid
    """
    print('\nPlayfair Grid:')
    for j in range(5):
        for i in range(5):
            print(key[i+j*5],'',end='')
        print()
    print()
    return

def showmsg(msg):
    """
    Break a string into digraphs
    """
    space=True
    for char in msg:
        print(char,end='')
        space = not space
        if space:
            print(' ',end='')
    print()
    return

def playfair(enc,msg,key):
    """
    Encrypt with playfair
    """
    # reversing the operation between encrypt and decrypt
    offset=-1
    if enc:
        offset=+1
    output=''
    for i in range(0,len(msg),2):
        # extract letters in digraph
        lett1=msg[i]
        lett2=msg[i+1]
        # find the key position
        pos1=key.find(lett1)
        pos2=key.find(lett2)
        # turn into coordinates
        coord1=[pos1%5,pos1//5]
        coord2=[pos2%5,pos2//5]
        # if in same row, shift along
        if coord1[0]==coord2[0]:
            coord1[1]=(coord1[1]+offset)%5
            coord2[1]=(coord2[1]+offset)%5
        # if in same col, shift vert
        elif coord1[1]==coord2[1]:
            coord1[0]=(coord1[0]+offset)%5
            coord2[0]=(coord2[0]+offset)%5
        # if on corners of rectangle, go for opp corners
        else:
            tmp=coord2[0]
            coord2[0]=coord1[0]
            coord1[0]=tmp
        # go back from coords to key position
        pos1=coord1[0]+5*coord1[1]
        pos2=coord2[0]+5*coord2[1]
        # pull the new letter
        lett1=key[pos1]
        lett2=key[pos2]
        # build the output
        output+=lett1
        output+=lett2
    return output

def showres(msg1,msg2):
    linesize=50
    for i in range(0,len(msg1),linesize):
        showmsg(msg1[i:i+min(linesize,len(msg1)-i)])
        showmsg(msg2[i:i+min(linesize,len(msg2)-i)])
        print()
    return


userkey=(input('Please type a key: ')+'abcdefghijklmnopqrstuvwxyz').upper()
key=massageKey(userkey)

usermsg=(input('Please type a message: ')).upper()
msg=massageMessage(usermsg)

chosen=False
while not chosen:
    choice=input('(E)ncrypt or (D)ecrypt  E/D  ? : ').upper()
    if choice=='E':
        enc=True
        chosen=True
    elif choice=='D':
        enc=False
        chosen=True

showgrid(key)

newmsg=playfair(enc,msg,key)

print('showing digraphs')
showres(msg,newmsg)

print('In one chunk:')
print(newmsg)

Links

Recent Cryptography

More Cryptography

Bennu Tag

Bennu Tag

A busy time for launches

A busy time for launches