Skip to content

Instantly share code, notes, and snippets.

@alanxoc3
Last active December 15, 2018 09:03
Show Gist options
  • Save alanxoc3/c5e28537f0beb27833453dce08ff0f72 to your computer and use it in GitHub Desktop.
Save alanxoc3/c5e28537f0beb27833453dce08ff0f72 to your computer and use it in GitHub Desktop.
A space efficient implementation of the Railway Cipher.
#!/usr/bin/env python3
# Railway Cipher, without a multidimensional array.
# Author: Alan Morgan
def get_rail_len(h): return 2*(h+1)-2
def get_level_len(level, fence_height, s):
rail_length = get_rail_len(fence_height)
rem = len(s) % rail_length - 1
level_len = len(s) // rail_length
if level != 0 and level != fence_height:
level_len *= 2
if rem >= 0+level: level_len+=1
if rem >= 2*fence_height-level: level_len+=1
elif rem >= level:
level_len += 1
return level_len
def get_fence_height(s, p, minimum_height=2):
p_val, divider = 0, 1 if len(s) < 2 else len(s)//2
for x in p: p_val += ord(x)
return (p_val % divider) + minimum_height
def get_final_index(level, level_ind, fence_height):
rail_length = get_rail_len(fence_height)
offset, level_divisor = level, 1
if level != 0 and level != fence_height:
level_divisor = 2
if level_ind % 2 == 1:
offset = rail_length - level
return offset+(level_ind//level_divisor)*(rail_length)
def base_algorithm(s, p, cipher, cipher_func):
# Fence Height
fence_height = get_fence_height(s, p)
# Next scramble the password.
level, level_ind = 0, 0
level_len = get_level_len(level, fence_height, s)
for i in range(len(s)):
final_ind = get_final_index(level, level_ind, fence_height)
cipher_func(cipher, s, i, final_ind)
level_ind = (level_ind + 1) % level_len
if level_ind == 0:
level += 1
level_len = get_level_len(level, fence_height, s)
return ''.join(x for x in cipher)
def encrypt_helper(c, s, i, f): c.append(s[f])
def decrypt_helper(c, s, i, f): c[f] = s[i]
encrypt = lambda s, p: base_algorithm(s, p, list(), encrypt_helper)
decrypt = lambda s, p: base_algorithm(s, p, list(s), decrypt_helper)
m = input("Enter your message: ")
k = input("Enter your key: ")
s = encrypt(m, k)
d = decrypt(s, k)
print("-------------"+"-"*len(s))
print("Encrypted: '{}'".format(s))
print("Decrypted: '{}'".format(d))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment