Last active
August 3, 2016 01:33
-
-
Save hyperreality/5b24faadd708a8a4ace324b7a42daed1 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
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
import random | |
code_points = { | |
'english': (32, 126), | |
'burmese': (1024, 1279), | |
'arabic': (1536, 1791), | |
'canadian_aboriginal': (5120, 5759), | |
'chinese': (19968, 40869), | |
'korean': (44032, 55216), | |
} | |
def unicodeCipher( | |
message, | |
mode, | |
plaintext=(32, 126), | |
ciphertext=(19968, 40869), | |
): | |
"""Unicode shift cipher | |
Args: | |
message (str): The plaintext to be enciphered. | |
mode (str): 'e' for encryption, 'd' for encryption. | |
plaintext (tuple): Tuple of the plaintext unicode start and end points. Defaults to ASCII plaintext. You can use one of the strings defined in the code_points dictionary. | |
ciphertext (tuple): Tuple of the ciphertext unicode start and end points. Defaults to Chinese. You can use one of the strings defined in the code_points dictionary. | |
""" | |
if mode != 'e' and mode != 'd': | |
raise ValueError('Mode must be e for encryption or d for decryption') | |
if type(plaintext) is str: | |
plaintext = code_points[plaintext] | |
if type(ciphertext) is str: | |
ciphertext = code_points[ciphertext] | |
plaintext_range = plaintext[1] - plaintext[0] + 1 | |
ciphertext_range = ciphertext[1] - ciphertext[0] | |
ciphertext_size = ciphertext_range / plaintext_range | |
if ciphertext_size < 1: | |
raise ValueError('Ciphertext code point range needs to be larger than plaintext code point range') | |
output = [] | |
if mode == 'e': | |
for letter in message: | |
unicode_decimal = ord(letter) - plaintext[0] + ciphertext[0] + plaintext_range * int(random.uniform(0, ciphertext_size) - 1) | |
output.append(chr(unicode_decimal)) | |
elif mode == 'd': | |
for letter in message: | |
unicode_decimal = (ord(letter) - ciphertext[0]) % plaintext_range + plaintext[0] | |
output.append(chr(unicode_decimal)) | |
return ''.join(output) | |
if __name__ == '__main__': | |
example_plaintext = 'This is a Unicode cipher' | |
example_ciphertext = unicodeCipher(example_plaintext, 'e', 'english', 'korean') | |
print('Ciphertext: ' + example_ciphertext) | |
print('Decrypted: ' + unicodeCipher(example_ciphertext, 'd', 'english', 'korean')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment