if (options.ct): options.ct = base64.b64decode(options.ct)
if (options.ct and not options.keyfile): parser.error("keyfile required for decryption; exiting...")
if (options.ct and options.pt) or (not options.ct and not options.pt): parser.error("either encrypt (-e \"foo\") or decrypt (-d \"bar\") must be specified; exiting...")
# this should really only be used in cases of encrypting
# ...or in brute forcing a ciphertext... poorly :)
alphabetCT = []; alphabetPT = []
if not options.keyfile:
# generate random alphabets
alphabet = [chr(i) for i in range(9, 126+1)] # default to 118 printable ASCII characters, numbered from 9 to 125 (decimal) (this includes tabs and newlines)
random.seed() # debugging be damned
random.shuffle(alphabet); alphabetCT = alphabet[:] # shuffle the alphabets...
random.shuffle(alphabet); alphabetPT = alphabet[:] # ...and point alphabetCT & alphabetPT to copies of the shuffled alphabets
# write alphabets to timestamped file for future decryption use
alphabetLen = len(alphabetCT) # optimization; theres no point in continually finding this; len(alphabetCT) = len(alphabetPT)
zenith = 0 # less code if this is global
# simulate left wheel permutation
def permuteLeft():
global zenith
# step 1: (already done by updating the zenith pointer in main)
extractedChar = alphabetCT[(zenith+1) % alphabetLen] # step 2: extract character at the zenith+1 position
alphabetCT[(zenith+1) % alphabetLen] = "*" # ...and replace with a flag
# step 3: (covered by modulo arithmetic)
nadir = (zenith + alphabetLen/2) % alphabetLen # step 4: point nadir to the "opposite" position of the zenith...
alphabetCT.insert(nadir+1, extractedChar) # ...insert removed character at this position...
alphabetCT.remove("*") # ...and remove flagged list entry
# simulate right wheel permutation
def permuteRight():
global zenith
# step 1: (already done by updating the zenith pointer in main)
alphabetPT.append(alphabetPT.pop(0)) # step 2: shift entire alphabet one to the left
extractedChar = alphabetPT[(zenith+2) % alphabetLen] # step 3: extract character at the zenith+2 position
alphabetPT[(zenith+2) % alphabetLen] = "*" # ...and replace with a flag
# step 4: (covered by modulo arithmetic)
nadir = (zenith + alphabetLen/2) % alphabetLen # step 5: point nadir to the "opposite" position of the zenith...
alphabetPT.insert(nadir+1, extractedChar) # ...insert removed character at this position...
alphabetPT.remove("*") # ...and remove flagged list entry
# ENCRYPTION
if options.pt:
plaintext = options.pt; ciphertext = ""
for character in plaintext:
# encrypt character
zenith = alphabetPT.index(character)
ciphertext += alphabetCT[zenith]
# permute "wheels"
permuteLeft()
permuteRight()
# DECRYPTION
if options.ct:
ciphertext = options.ct; plaintext = ""
for character in ciphertext:
# decrypt character
try: zenith = alphabetCT.index(character)
except: print "ERROR: Could not find a required character in the provided ciphertext alphabet. Usually this means you are using an incorrect keyfile during decryption."; exit(1)