Skip to content

Instantly share code, notes, and snippets.

@hyperreality
Last active August 3, 2016 01:33

Revisions

  1. hyperreality renamed this gist Aug 3, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion Unicode Substitution Cipher → Unicode Shift Cipher
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ def unicodeCipher(
    plaintext=(32, 126),
    ciphertext=(19968, 40869),
    ):
    """Unicode substitution cipher
    """Unicode shift cipher
    Args:
    message (str): The plaintext to be enciphered.
  2. hyperreality created this gist Jul 31, 2016.
    68 changes: 68 additions & 0 deletions Unicode Substitution Cipher
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    #!/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 substitution 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'))