#!/usr/bin/python2 import sys, readline #Which characters should be translated? Uncomment as many lines as you like. increment = '' #Lowercase letters. increment+= 'abcdefghijklmnopqrstuvwxyz' #Uppercase letters increment+= 'abcdefghijklmnopqrstuvwxyz'.upper() #Numbers #increment+= '1234567890' #Whitespace #increment+= ' \t\n' #Basic punctuation #increment+= '.,\'\"?' #Advanced punctuation #increment+= '`~!@#$%^&*_+-=|\\;:/<>' #Braces #increment+= '{}[]()' def main(): #Parse arguments global mode cyphertext, transpose, mode, output = args() #Print out the cypher, as interpreted. print >> sys.stderr, "Transpostion pattern: "+transpose+'\n' #Parse the cyphertext. final = parse(cyphertext, transpose) print final if output != '': writer = open(output, 'w') writer.write(final) writer.close() def args(): help = """One time pad decoder. Run as otp.py Encoding, passphrase, and cyphertext must be specified. Other arguments are optional. If multiple arguments override each other, the last one takes precedence. If there are spaces in filenames, passwords, or other text, enclose the argument in quotes. Options: -d Decode text -e Encode text -pf Specify a password file. -p Specify a passphrase. -cf File to decode. -c Text to decode. -o File to output encrypted text to. (optional) -h This help text. """ #Output is returned, so must be something. output = '' for x in range(len(sys.argv)): arg = sys.argv[x] #Encrypt/decrypt if arg == '-d': mode = -1 if arg == '-e': mode = 1 #Passphrase if arg == '-p': passphrase = sys.argv[x+1] if arg == '-pf': passphrase = open(sys.argv[x+1], 'r').read() #Cyphertext if arg == '-c': cypher = sys.argv[x+1] if arg == '-cf': cypher = open(sys.argv[x+1], 'r').read() #Output if arg == '-o': output = sys.argv[x+1] #Help if arg == '-h': print >> sys.stderr, help try: return cypher, passphrase, mode, output except: print "Missing required arguments! Check your syntax.\n\n".upper()+help exit() #Parses the cypher, for a given starting index, a given transposition matrix, #and given cyphertext. def parse(string, transpose): index = 0 newstring = '' for char in string: #Translate this character? if (char in increment): newstring += translate(char, transpose[index]) index = (index + 1 ) % len(transpose) else: newstring += char return newstring #Translates a character by an offset. Supports any alpha characters. Numbers #and symbols will wonk. def translate(char, offset): if (offset.islower()): offset = ord(offset) - ord('a') elif (offset.isupper()): offset = ord(offset) - ord('A') if (char.islower()): fix = ord('a') elif (char.isupper()): fix = ord('A') elif (char.isdigit()): fix = ord('0') #Not sure if this'll work... XXX if (char.isalpha()): mod = 26 elif (char.isdigit()): mod = 10 #If fix is still 0, weird stuff will happen here. Everything will map to #ASCII 0-26, which is garbage. And it won't unmap. val = ((ord(char) - fix + (mode * offset)) % mod) + fix return chr(val) main()