Skip to content

Instantly share code, notes, and snippets.

@efruchter
Last active August 29, 2015 14:01
Show Gist options
  • Save efruchter/d0e65727859f1ad405dc to your computer and use it in GitHub Desktop.
Save efruchter/d0e65727859f1ad405dc to your computer and use it in GitHub Desktop.
Some basic ciphers for infosec.
#python 2.7
from __future__ import division
padding = '|'
cipher_key = 'abcdefghijklmnopqrstuvwxyz '
cipher_key_length = len(cipher_key)
# A shift cipher. Can also use a key, turning it into a vernam cipher.
# text = the text
# key = the key. Can be a number or a string.
# shift_forward = whether the shift goes forward or back. Set to False to decrypt.
def shift(text, key, shift_forward=True):
# Shift direction
forward = 1 if shift_forward else -1
key_length = len(key)
# Convert numerical keys to tiny shift key
if type(key) is int: key = cipher_key[key]
ciphertext = ''
# Perform the shift
for decode_index, c in enumerate(text):
shifted_pos = cipher_key.index(c) + \
(forward * cipher_key.index(key[decode_index % key_length]))
ciphertext += cipher_key[shifted_pos % cipher_key_length]
return ciphertext
# A columnar transposition cipher. Encrypt only.
# plaintext = the text to encrypt
# keyphrase = the keyphrase. Make sure it has unique letters! Lowercase only!
def transposition_encode(plaintext, keyphrase):
# Length of keyphrase
row_length = len(keyphrase)
# Fragment the plaintext into rows
rows = [plaintext[i:i + row_length] for i in range(0, len(plaintext), row_length)]
# Pad the last row if needed
rows[-1] += padding * (row_length - len(rows[-1]))
# Arrange keyphrase in abc order
abc_order = sorted(keyphrase, key = lambda c : cipher_key.index(c))
ciphertext = ''
# Read in the characters by column, in abc order
for col in [keyphrase.index(c) for c in abc_order]:
for row in rows:
ciphertext += row[col]
return ciphertext
# A columnar transposition cipher. Decryption only.
# ciphertext = the text to decrypt.
# keyphrase = the keyphrase. Make sure it has unique letters! Lowercase only!
def transposition_decode(ciphertext, keyphrase):
# Get the column lengths
col_length = len(ciphertext) // len(keyphrase)
# Break the ciphertext into column groups
cols = [ciphertext[i:i + col_length] for i in range(0, len(ciphertext), col_length)]
# Arrange keyphrase in abc order
abc_order = sorted(keyphrase, key = lambda c : cipher_key.index(c))
# Re-order the columns according to the keyphrase
ordered_cols = [None] * len(cols)
for i, key_char in enumerate(abc_order):
ordered_cols[keyphrase.index(key_char)] = cols[i]
plaintext = ''
# Read in the characters down each row
for i in range(col_length):
for col in ordered_cols:
plaintext += col[i]
# Strip the padding
plaintext = plaintext.replace(padding, '')
return plaintext
def test():
print shift(shift('this should be readable', 'abacab'), 'abacab', False)
s = 'we are discovered flee at once'
key = 'zebras'
coded = transposition_encode(s, key)
print s, '->', coded, '->', transposition_decode(coded, key)
from random import shuffle
# Set up the cipher's key
_cipher_key = list('abcdefghijklmnopqrstuvwxyz ')
_cipher_subs = _cipher_key[:]
shuffle(_cipher_subs)
def encrypt(plaintext):
ciphertext = ''
for c in plaintext:
ciphertext += _cipher_subs[_cipher_key.index(c)]
return ciphertext
def decrypt(plaintext):
ciphertext = ''
for c in plaintext:
ciphertext += _cipher_key[_cipher_subs.index(c)]
return ciphertext
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment