Created
May 1, 2020 19:58
-
-
Save erjiang/5ba01d43922fdf8c62818ce23e2e2b86 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import secrets | |
import string | |
from typing import Sequence | |
""" | |
This is a set of functions for demonstrating one-time pad | |
encryption using a twenty-six letter alphabet. | |
This code is a companion to the article at | |
https://notes.ericjiang.com/posts/1051 | |
""" | |
def add_text(text1: str, text2: str) -> str: | |
""" | |
>>> add_text('HELLO', 'ABCDE') | |
'HFNOS' | |
""" | |
return "".join([ | |
number_to_char( | |
(char_to_number(c1) + char_to_number(c2)) % 26 | |
) | |
for c1, c2 in zip(text1, text2)]) | |
def subtract_text(text1: str, text2: str) -> str: | |
""" | |
Given two strings of equal length, subtract each letter in `text2` | |
from the corresponding letter in `text1`. | |
>>> subtract_text('HELLO', 'ABCDE') | |
'HDJIK' | |
""" | |
return "".join([ | |
number_to_char( | |
(char_to_number(c1) - char_to_number(c2)) % 26 | |
) | |
for c1, c2 in zip(text1, text2)]) | |
def strip_spaces(text: str) -> str: | |
""" | |
Removes all space characters from a string. | |
>>> strip_spaces("Hello world") | |
'Helloworld' | |
""" | |
return text.replace(" ", "") | |
def random_key(length: int) -> str: | |
""" | |
Creates a random string of letters of `length` characters. | |
>>> random_key(5) | |
'CKMML' | |
""" | |
return ''.join(secrets.choice(string.ascii_uppercase) for _ in range(length)) | |
def char_to_number(char: str) -> int: | |
char = char.upper() | |
if ord(char) < ord('A') or ord(char) > ord('Z'): | |
raise ValueError("character out of range") | |
return ord(char) - ord('A') | |
def number_to_char(num: int) -> str: | |
if num < 0 or num > 25: | |
raise ValueError("number out of range") | |
return chr(num + ord('A')) | |
def text_to_nums(text: str) -> Sequence[int]: | |
return [char_to_number(x) for x in text] | |
def nums_to_text(nums: Sequence[int]) -> str: | |
return "".join([number_to_char(x) for x in nums]) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment