cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, "A", 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, "B", 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52] ##cards = [21, 22, 29, 26, 27, 11, 31, 32, 33, 34, 35, 36, 6, 39, 17, 25, 41, 10, 14, 44, 49, "A", 13, 43, 46, 52, 12, 48, 37, 38, 28, 7, 42, 45, 8, "a", "b", "c", "d", "e", "f", "g", "h", "B", "i", "j", "k", "l", "m", "n", 24, "o", 20, "p"] ##cards = [21, 22, 29, 26, 27, 11, 31, 32, 33, 34, 35, 36, 6, 39, 17, 25, 41, 10, 14, 44, 49, "A", 13, 43, 46, 52, 12, 48, 37, 38, 28, 7, 42, 45, 8, 51, "b", "c", "d", 18, "f", "g", 50, "B", 4, "j", 30, "l", "m", "n", 24, 15, 20, "p"] ##cards = [21, 22, 29, 26, 27, 11, 31, 32, 33, 34, 35, 36, 6, 39, 17, 25, 41, 10, 14, 44, 49, "A", 13, 43, 46, 52, 12, 48, 37, 38, 28, 7, 42, 45, 8, 51, "b", "c", 16, 18, "f", "g", 50, "B", 4, "j", 30, "l", "m", "n", 24, 15, 20, "p"] ##cards = [21, 22, 29, 26, 27, 11, 31, 32, 33, 34, 35, 36, 6, 39, 17, 25, 41, 10, 14, 44, 49, "A", 13, 43, 46, 52, 12, 48, 37, 38, 28, 7, 42, 45, 8, 51, "b", 23, 16, 18, "f", "g", 50, "B", 4, 5, 30, "l", "m", "n", 24, 15, 20, "p"] def next(deck): deck = deck[:] try: # Find joker A and move it one place down for i in xrange(len(deck)): if deck[i] == "A": deck[i] = deck[(i + 1) % len(deck)] deck[(i + 1) % len(deck)] = "A" apos = (i + 1) % len(deck) break # Find joker B and move it two places down for i in xrange(len(deck)): if deck[i] == "B": deck[i] = deck[(i + 1) % len(deck)] deck[(i + 1) % len(deck)] = deck[(i + 2) % len(deck)] deck[(i + 2) % len(deck)] = "B" bpos = (i + 2) % len(deck) break # Perform a triple cut if apos > bpos: store = bpos bpos = apos apos = store deck = deck[bpos + 1:] + deck[apos:bpos + 1] + deck[:apos] # Perform a count cut count = deck[-1] if count == "A" or count == "B": count = 53 deck = deck[count:len(deck) - 1] + deck[:count] + [deck[-1]] except: pass return deck def value(deck): try: count = deck[0] if count == "A" or count == "B": count = 53 if deck[count] == "A" or deck[count] == "B": return -1 if deck[count] % 26 == 0: return 26 else: return deck[count] % 26 except: return 0 def stream(deck, amount): deck = deck[:] result = "" alphabet = "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" for i in xrange(amount): deck = next(deck) while value(deck) == -1: deck = next(deck) result += alphabet[value(deck)] print "Deck after generating key:\n" + str(deck) return result def enc(plaintext, deck): shift = 1 plaintext = plaintext.upper() key = stream(deck, len(plaintext)) alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ciphertext = "" keypos = 0 for character in plaintext: if alphabet.find(character) != -1: ciphertext += alphabet[(alphabet.find(character) + alphabet.find(key[keypos]) + shift) % len(alphabet)] keypos = (keypos + 1) % len(key) else: ciphertext += character return ciphertext def dec(ciphertext, deck): shift = 1 ciphertext = ciphertext.upper() key = stream(deck, len(ciphertext)) alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" plaintext = "" keypos = 0 for character in ciphertext: if alphabet.find(character) != -1: plaintext += alphabet[(alphabet.find(character) - alphabet.find(key[keypos]) - shift) % len(alphabet)] keypos = (keypos + 1) % len(key) else: plaintext += character return plaintext def perms(data): if len(data) == 1: return [data] result = [] for i in range(len(data)): dat = perms(data[:i] + data[i + 1:]) for d in dat: result += [[data[i]] + d] return result