def vigenere(plaintext, key): ciphertext = str() for (char, current_key) in zip(plaintext, key): current_shift = ALPHABET.index(current_key) shifted_char = substitute(char, ALPHABET, lambda x: x + current_shift) shifted_char = substitute(shifted_char, ALPHABET_LOWERCASE, lambda x: x + current_shift) ciphertext += shifted_char return ciphertext
def first_sifra(data, key): """first bellaso substitution cipher""" alphabet = "abcdefghilmnopqrstvxyz" # bellaso didn't use a 26 chars alphabet constant_part, rotated_part = alphabet[:11], Str( alphabet[11:]) # and it was split in two parts, used differently pairs = [ alphabet[i:i + 2] for i in range(0, len(alphabet), 2) ] #each pair of letters of the key gets a different substitution alphabet order = "aeiovcgmqsy" # this is the order of pairs, rotation-wise. # now let's generate the substitution alphabet for each pair # at each step (following the right order), the rotated part is rotated left one character alphabets = dict() for index, char in enumerate(order): #let's get the pair by its first char in the order current_pair = [pair for pair in pairs if char in pair][0] alphabets[current_pair] = constant_part + (rotated_part >> index) output = str() for char, current_key in zip(data, key): pair = [p for p in alphabets if current_key in p] if pair: char = substitute(char, alphabets[pair[0]]) output += char return output
def second_sifra(data, key, alphabet_key): #now the substitution alphabet is generated from a passphrase consonants = mix_alphabet(alphabet_key, "bcdfghlmnpqrstxyz") #then we'll work on the vowels, but we'll insert them every 3 character #let's split the consonants string consonants_blocks = split_string_blocks(consonants, 3) #and parse the key for its used vowels vowels = mix_alphabet(alphabet_key, "aeiou") #let's merge the consonants and vowels data alphabet = "".join(i + j for i, j in zip_extend(consonants_blocks, list(vowels))) #assert alphabet == "rmqacntupsbidfgehlxoyz" constant_part, rotated_part = alphabet[:11], Str(alphabet[11:]) #now to generate the pairs, we'll do the same, but merge the vowel every char blocks consonants_blocks = split_string_blocks(consonants, 1) pairsString = Str("".join( i + j for i, j in zip_extend(consonants_blocks, list(vowels)))) pairs = pairsString.splitblock(2) #now we have the pairs, the initial substitution alphabet #let's generate the 'rotated' alphabet for each pair alphabets = dict() for index, pair in enumerate(pairs): #let's get the pair by its first char in the order alphabets[pair] = constant_part + (rotated_part >> index) # now the actual encryption # for this cipher, the xth character of the key is used to decrypt the xth word (space separated) of the plaintext output = str() key_index = 0 for char in data: pair = [p for p in alphabets if key[key_index] in p] if pair: char = substitute(char, alphabets[pair[0]]) if char == ' ': key_index += 1 output += char return output
def second_sifra(data, key, alphabet_key): #now the substitution alphabet is generated from a passphrase consonants = mix_alphabet(alphabet_key, "bcdfghlmnpqrstxyz") #then we'll work on the vowels, but we'll insert them every 3 character #let's split the consonants string consonants_blocks = split_string_blocks(consonants, 3) #and parse the key for its used vowels vowels = mix_alphabet(alphabet_key, "aeiou") #let's merge the consonants and vowels data alphabet = "".join(i + j for i, j in zip_extend(consonants_blocks, list(vowels))) #assert alphabet == "rmqacntupsbidfgehlxoyz" constant_part, rotated_part = alphabet[:11], Str(alphabet[11:]) #now to generate the pairs, we'll do the same, but merge the vowel every char blocks consonants_blocks = split_string_blocks(consonants, 1) pairsString = Str("".join(i + j for i, j in zip_extend(consonants_blocks, list(vowels)))) pairs = pairsString.splitblock(2) #now we have the pairs, the initial substitution alphabet #let's generate the 'rotated' alphabet for each pair alphabets = dict() for index, pair in enumerate(pairs): #let's get the pair by its first char in the order alphabets[pair] = constant_part + (rotated_part >> index) # now the actual encryption # for this cipher, the xth character of the key is used to decrypt the xth word (space separated) of the plaintext output = str() key_index = 0 for char in data: pair = [p for p in alphabets if key[key_index] in p] if pair: char = substitute(char, alphabets[pair[0]]) if char == ' ': key_index += 1 output += char return output
def first_sifra(data, key): """first bellaso substitution cipher""" alphabet = "abcdefghilmnopqrstvxyz" # bellaso didn't use a 26 chars alphabet constant_part, rotated_part = alphabet[:11], Str(alphabet[11:]) # and it was split in two parts, used differently pairs = [alphabet[i:i + 2] for i in range(0, len(alphabet), 2)] #each pair of letters of the key gets a different substitution alphabet order = "aeiovcgmqsy" # this is the order of pairs, rotation-wise. # now let's generate the substitution alphabet for each pair # at each step (following the right order), the rotated part is rotated left one character alphabets = dict() for index, char in enumerate(order): #let's get the pair by its first char in the order current_pair = [pair for pair in pairs if char in pair][0] alphabets[current_pair] = constant_part + (rotated_part >> index) output = str() for char, current_key in zip(data, key): pair = [p for p in alphabets if current_key in p] if pair: char = substitute(char, alphabets[pair[0]]) output += char return output
# #Kabopan - Readable Algorithms. Public Domain, 2007-2009 from kbp._subst import substitute, mix_alphabet assert substitute("a", "abcd") == "c" assert substitute("a", "abcd", lambda x: x + 3) == "d" assert substitute("ac", "abcd") == "ca" assert substitute("ac", "abcd", lambda x: x + 3) == "db" assert mix_alphabet("PLAYFAIR EXAMPLE", "ABCDEFGHIJKLMNOPRSTUVWXYZ") == \ "PLAYFIREXMBCDGHJKNOSTUVWZ"
def caesar_decode(ciphertext): return substitute(ciphertext, ALPHABET, lambda x: x - 3)
def caesar_encode(plaintext): return substitute(plaintext, ALPHABET, lambda x: x + 3)
def rot47(data): return substitute(data, ASCII33_126)
def rot13(data): return substitute(substitute(data, ALPHABET), ALPHABET_LOWERCASE)
def encode(plaintext, alphabet, increment, multiplier,): assert gcd(multiplier, len(alphabet)) == 1 # multiplier and length have to be co-primes ciphertext = substitute(plaintext, alphabet, lambda x: x * multiplier + increment) return ciphertext
def rot5(data): return substitute(data, DIGITS)
def decode(ciphertext, alphabet, increment, multiplier): modulo = len(alphabet) assert gcd(multiplier, modulo) == 1 # multiplier and length have to be co-primes multiplier_inverse = inverse(multiplier, modulo) # TODO plaintext = substitute(ciphertext, alphabet, lambda x: multiplier_inverse * (x - increment)) return plaintext