#! /usr/bin/env python
# One-Time Pad
# By: Magnie (http://scratch.mit.edu/users/Magnie)
# Copyright: GPLv3 (http://www.gnu.org/copyleft/gpl.html)
# I don't know why I bother adding this. I doubt my code will be used
# anyways, since it's probably not worth using. :P
import random
class OneTime(object):
"""
An attempt to make a one-time pad encryption system work with a key
smaller than the text.
It relies on a secure Pseudo-Random Generator (random.Random in this
case), and based on the seed/password/key given, it will generate a
"random" key, allowing the transferring of smaller, simpler (yet more
breakable), keys.
This follows the same caveats as the original One-Time Pad
protocol. For example, you can only use the key once (unless you send
a message/file of a different size than any others sent).
"""
def __init__(self):
"""This sets up everything needed"""
# This mostly just saves all the data in the class for later
# retrieval.
self.string = ""
self.key = []
self.seed = ""
self.cipher = ""
def generate_key(self):
"""
Based on the seed given, and the length of the file, the
final key will be different.
"""
key = []
seed = sum([ord(x) + len(self.string) for x in self.seed])
generator = random.Random(seed) # Random number generator.
for i in xrange(0, len(self.string) - 1):
t1 = generator.random() # Generate random number
t2 = int(str(t1)[2:5]) # Since it's going to be a decimal
# take the three digits after the
# decimal point.
key.append(t2)
self.key = [int(x) % 255 for x in key] # Removable.
return self.key
def encrypt(self):
"""Runs the original One-Time Pad encryption"""
cipher = ""
key = self.key
n = 0
for i in self.string:
# Shift the letter and modulo it to keep it in correct
# range to be put in binary format. Keeping the cipher
# the same length as the original text.
t1 = (ord(i) ^ key[n % len(key)]) % 255
cipher += chr(t1)
n += 1
self.cipher = cipher
return cipher
def decrypt(self):
"""Runs the original One-Time Pad decryption"""
plain = ""
key = self.key
n = 0
for i in self.cipher:
t1 = (ord(i) ^ key[n % len(key)]) % 255
plain += chr(t1)
n += 1
self.plain = plain
return plain
if __name__ == "__main__": # Just a list of tests.
time = OneTime()
time.seed = "testing12" # Original test - Set the seed
time.string = "I am awesome." # Set the string
print time.generate_key() # Generate key from seed
print time.encrypt() # Encrypt the data
print time.decrypt() # Decrypt the data
time.seed = "testing13" # One bit difference in key
print time.generate_key()
print time.encrypt()
print time.decrypt()
time.seed = "testing12" # Different length of string.
time.string = "I am awesome!!"
print time.generate_key()
print time.encrypt()
print time.decrypt()
time.seed = "testing12" # Same length, different letters.
time.string = "I am awesome!"
print time.generate_key()
print time.encrypt()
print time.decrypt()