Welcome to HBH! If you have tried to register and didn't get a verification email, please using the following link to resend the verification email.

Solitaire encryptor/decryptor - Python Code Bank


Solitaire encryptor/decryptor
After reading 'Cryptonomicon' by Neal Stephenson I decided to try to write a program to encrypt and decrypt codes with th Solitaire algorithm from the book. I know there is a lot of code out there already that does this, but this is my version using python. If you give it a key(the starting order of the deck) it will encrypt or decrypt a message. If you don't give it a key, it can encrypt the message using a pseudo random key, then print out the key that it used so that decryption is possible.
                ##Performs the solitaire cypher

import random

cardDict = {'Ac':1, '2c':2, '3c':3, '4c':4, '5c':5, '6c':6, '7c':7, '8c':8, '9c':9, '10c':10, 'Jc':11, 'Qc':12, 'Kc':13, \
            'Ad':14, '2d':15, '3d':16, '4d':17, '5d':18, '6d':19, '7d':20, '8d':21, '9d':22, '10d':23, 'Jd':24, 'Qd':25, 'Kd':26, \
            'Ah':27, '2h':28, '3h':29, '4h':30, '5h':31, '6h':32, '7h':33, '8h':34, '9h':35, '10h':36, 'Jh':37, 'Qh':38, 'Kh':39, \
            'As':40, '2s':41, '3s':42, '4s':43, '5s':44, '6s':45, '7s':46, '8s':47, '9s':48, '10s':49, 'Js':50, 'Qs':51, 'Ks':52, \
            'Ja':53, 'Jb':53}

class Deck:
    def __init__(self, key = None):
        self.key = key
        if(key != None):
            self.cards = key
        else:
            self.cards = []
            for card in cardDict:
                self.cards.append(card)
            self.shuffle()
            print  'Key:', self.cards

    def shuffle(self):
        for i in range(1000):
            a = random.randint(0, 53)
            b = random.randint(0, 53)
            self.cards[a], self.cards[b] = self.cards[b], self.cards[a]        
        
    def moveJa(self):
        i = self.cards.index('Ja')
        if(i == 53):
            self.cards.remove('Ja')
            self.cards.insert(1, 'Ja')
        else:
            self.cards.insert(i + 2, 'Ja')
            self.cards.remove('Ja')            
        
    def moveJb(self):
        i = self.cards.index('Jb')
        if(i == 52):
            self.cards.remove('Jb')
            self.cards.insert(1, 'Jb') 
        if(i == 53):
            self.cards.remove('Jb')
            self.cards.insert(2, 'Jb')
        else:
            self.cards.insert(i + 3, 'Jb')
            self.cards.remove('Jb')            
            
    def tripleCut(self):
        i = self.cards.index('Ja')
        j = self.cards.index('Jb')

        if(i < j):
            self.performTriple(i, j)
        else:
            self.performTriple(j, i)

    def performTriple(self, a, b):
        before = []
        after = []
        for i in range(a):
            before.append(self.cards[0])
            self.cards.pop(0)
        for i in range(53 - b):
            after.append(self.cards[-1])
            self.cards.pop(-1)
        for i in after:
            self.cards.insert(0, i)
        for i in before:
            self.cards.append(i)
            
    def cut(self):
        i = cardDict[self.cards[53]]
        if(i == 53):
            self.moveJa()
            self.moveJb()
            self.tripleCut()
            self.cut()
        else:
            for j in range(0, i):
                card = self.cards[0]
                self.cards.remove(card)
                self.cards.insert(52, card)
        
    def getNextNum(self):
        self.moveJa()
        self.moveJb()
        self.tripleCut()
        self.cut()
        
        i = cardDict[self.cards[0]]
        return cardDict[self.cards[i]]

class encypher:
    def __init__(self, text, key = None):
        self.plainText = text
        self.key = key
        self.theDeck = Deck(key)
        self.encodedText = ''
        self.encode()
        print self.encodedText

    def encode(self):
        text = self.plainText.upper()
        count = 0
        for letter in text:
            if(letter == ' '):
                continue
            if(count > 0 and count % 5 == 0):
                self.encodedText += ' '
            self.getNextLetter(letter)            
            count += 1
        numX = 5 - (count % 5)
        if(numX < 5):
            for i in range(numX):
                self.getNextLetter('X')
            
    def getNextLetter(self, letter):
        currentNum = ord(letter)
        addNum = self.theDeck.getNextNum()
        while(addNum == 53):
            addNum = self.theDeck.getNextNum()
        self.encodedText += chr(65 + ((currentNum + addNum) % 26))
            
class decypher:
    def __init__(self, text, key):
        self.encodedText = text
        self.key = key
        self.theDeck = Deck(key)
        self.plainText = ''
        self.decode()
        print self.plainText

    def decode(self):
        text = self.encodedText.upper()

        for letter in text:
            if(letter == ' '):
                self.plainText += ' '
            else:
                self.getNextLetter(letter)

    def getNextLetter(self, letter):
        currentNum = ord(letter)
        subNum = self.theDeck.getNextNum()
        while(subNum == 53):
            subNum = self.theDeck.getNextNum()
        self.plainText += chr(65 + ((currentNum - subNum) % 26))

            
Comments
Sorry but there are no comments to display