Skip to content

Instantly share code, notes, and snippets.

Created September 17, 2009 07:22
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save cdleary/188393 to your computer and use it in GitHub Desktop.
"""Instructional implementation of Ron's Cipher #4 (AKA RC4).
Follows form of a `Programming Praxis exercise`_.
.. _Programming Praxis exercise:
:author: Christopher D. Leary <>
import textwrap
import readline
except ImportError: # Only available on POSIX, but no big deal.
def initialize(key):
"""Produce a 256-entry list based on `key` (a sequence of numbers)
as the first step in RC4.
Note: indices in key greater than 255 will be ignored.
k = range(256)
j = 0
for i in range(256):
j = (j + k[i] + key[i % len(key)]) % 256
k[i], k[j] = k[j], k[i]
return k
def gen_random_bytes(k):
"""Yield a pseudo-random stream of bytes based on 256-byte array `k`."""
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + k[i]) % 256
k[i], k[j] = k[j], k[i]
yield k[(k[i] + k[j]) % 256]
def run_rc4(k, text):
cipher_chars = []
random_byte_gen = gen_random_bytes(k)
for char in text:
byte = ord(char)
cipher_byte = byte ^
return ''.join(cipher_chars)
# Command line interface functionality follows.
def loop_user_query(k):
"""Raises EOFError when the user uses an EOT escape sequence (i.e. ^D)."""
quotes = "'\""
while True:
text = raw_input('Enter plain or cipher text: ')
if text[0] == text[-1] and text[0] in quotes:
# Unescape presumed ciphertext.
print 'Unescaping ciphertext...'
text = text[1:-1].decode('string_escape')
k_copy = list(k)
print 'Your RC4 text is:', repr(run_rc4(k_copy, text))
def print_prologue():
title = 'RC4 Utility'
print '=' * len(title)
print title
print '=' * len(title)
explanation = """The output values are valid Python strings. They may
contain escape characters of the form \\xhh to avoid confusing your terminal
emulator. Only the first 256 characters of the encryption key are used."""
for line in textwrap.wrap(explanation, width=79):
print line
def main():
"""Present a command-line interface to the cipher."""
# Acquire initial cipher values.
key = raw_input('Enter an encryption key: ')
key = [ord(char) for char in key]
k = initialize(key)
# Perform cipher until exit.
except EOFError:
print 'Have a pleasant day!'
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment