Skip to content

Instantly share code, notes, and snippets.

@dssstr
Last active December 16, 2023 09:01
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save dssstr/aedbb5e9f2185f366c6d6b50fad3e4a4 to your computer and use it in GitHub Desktop.
Save dssstr/aedbb5e9f2185f366c6d6b50fad3e4a4 to your computer and use it in GitHub Desktop.
Simple Vigenere Cipher written in Python 3.5.
def encrypt(plaintext, key):
key_length = len(key)
key_as_int = [ord(i) for i in key]
plaintext_int = [ord(i) for i in plaintext]
ciphertext = ''
for i in range(len(plaintext_int)):
value = (plaintext_int[i] + key_as_int[i % key_length]) % 26
ciphertext += chr(value + 65)
return ciphertext
def decrypt(ciphertext, key):
key_length = len(key)
key_as_int = [ord(i) for i in key]
ciphertext_int = [ord(i) for i in ciphertext]
plaintext = ''
for i in range(len(ciphertext_int)):
value = (ciphertext_int[i] - key_as_int[i % key_length]) % 26
plaintext += chr(value + 65)
return plaintext
@v1a0
Copy link

v1a0 commented Jan 20, 2022

Vigenere Cipher for any Unicode text

[ ! ] text and key have to be unicode encoding

def vigenere(text: str, key: str, encrypt=True):

    result = ''

    for i in range(len(text)):
        letter_n = ord(text[i])
        key_n = ord(key[i % len(key)])

        if encrypt:
            value = (letter_n + key_n) % 1114112
        else:
            value = (letter_n - key_n) % 1114112

        result += chr(value)

    return result
    

def vigenere_encrypt(text: str, key: str):
    return vigenere(text=text, key=key, encrypt=True)


def vigenere_decrypt(text: str, key: str):
    return vigenere(text=text, key=key, encrypt=False)

Example

>>> vigenere_encrypt(u"Hello world!", u"Leet1337:)")
'\x94ÊÑà\xa0Sª¦¬\x95°\x86'

>>> vigenere_decrypt(u"\x94ÊÑà\xa0Sª¦¬\x95°\x86", u"Leet1337:)")
'Hello world!'

@v1a0
Copy link

v1a0 commented Jan 20, 2022

Vigenere Cipher for specific alphabet

def vigenere(
        text: str, 
        key: str, 
        alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
        encrypt=True
):

    result = ''

    for i in range(len(text)):
        letter_n = alphabet.index(text[i])
        key_n = alphabet.index(key[i % len(key)])

        if encrypt:
            value = (letter_n + key_n) % len(alphabet)
        else:
            value = (letter_n - key_n) % len(alphabet)

        result += alphabet[value]

    return result


def vigenere_encrypt(text, key):
    return vigenere(text=text, key=key, encrypt=True)


def vigenere_decrypt(text, key):
    return vigenere(text=text, key=key, encrypt=False)

Example

vigenere_encrypt('Python', 'secretWORD')
'HcVYSg'

vigenere_decrypt('HcVYSg', 'secretWORD')
'Python'

P.S. Please note that the alphabet from the example is missing a space, so trying to encrypt several words will throw an exception!

vigenere_encrypt('Hello world', 'SecRet')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 34, in vigenere_encrypt
  File "<input>", line 16, in vigenere
ValueError: substring not found

For fix it, just add space into the alphabet

...
alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ', # <--- HERE
...

@SHTEFOZOID
Copy link

bravo Raihan!! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment