def decode(ciphertext, key): square = mix_alphabet(key, ALPHABET25) digraphs = split_string_blocks(ciphertext, 2) plaintext = str() for digraph in digraphs: #get both chars, their coordinates char1, char2 = list(digraph) row1, column1 = get_coordinates(square, char1) row2, column2 = get_coordinates(square, char2) encoded_row1, encoded_column1 = row1, column1 encoded_row2, encoded_column2 = row2, column2 #apply transformation rules if row1 != row2 and column1 != column2: # making a rectangle - take the other 2 corners, with the same row respectively encoded_row1, encoded_column1 = row1, column2 encoded_row2, encoded_column2 = row2, column1 elif row1 != row2 and column1 == column2: # same column - get the caracter up encoded_row1 = (row1 - 1) % 5 encoded_row2 = (row2 - 1) % 5 elif row1 == row2 and column1 != column2: # same row - get the caracter left encoded_column1 = (column1 - 1) % 5 encoded_column2 = (column2 - 1) % 5 #output resulting chars encoded_char1 = get_char(square, encoded_row1, encoded_column1) encoded_char2 = get_char(square, encoded_row2, encoded_column2) plaintext += encoded_char1 + encoded_char2 return plaintext
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 encode(plaintext, key): square = mix_alphabet(key, ALPHABET25) plaintext = plaintext.replace(" ","").upper() #let's split the plaintext in digraph, while inserting X to avoid single letter digraphs i = 0 digraphs = list() while i < len(plaintext) - 1: if i == len(plaintext) - 1: # wrong if last char is X plaintext = insert_string(plaintext, i + 1, 'X') elif i < len(plaintext) - 1 and plaintext[i] == plaintext[i + 1]: plaintext = insert_string(plaintext, i + 1, 'X') digraphs += [plaintext[i:i + 2]] i += 2 ciphertext = str() for digraph in digraphs: #get both chars, their coordinates char1, char2 = list(digraph) row1, column1 = get_coordinates(square, char1) row2, column2 = get_coordinates(square, char2) encoded_row1, encoded_column1 = row1, column1 encoded_row2, encoded_column2 = row2, column2 #apply transformation rules if row1 != row2 and column1 != column2: # making a rectangle - take the other 2 corners, with the same row respectively encoded_row1, encoded_column1 = row1, column2 encoded_row2, encoded_column2 = row2, column1 elif row1 != row2 and column1 == column2: # same column - get the caracter down encoded_row1 = (row1 + 1) % 5 encoded_row2 = (row2 + 1) % 5 elif row1 == row2 and column1 != column2: # same row - get the caracter right encoded_column1 = (column1 + 1) % 5 encoded_column2 = (column2 + 1) % 5 #output resulting chars encoded_char1 = get_char(square, encoded_row1, encoded_column1) encoded_char2 = get_char(square, encoded_row2, encoded_column2) ciphertext += encoded_char1 + encoded_char2 return ciphertext
def encode(plaintext, key): square = mix_alphabet(key, ALPHABET25) plaintext = plaintext.replace(" ", "").upper() #let's split the plaintext in digraph, while inserting X to avoid single letter digraphs i = 0 digraphs = list() while i < len(plaintext) - 1: if i == len(plaintext) - 1: # wrong if last char is X plaintext = insert_string(plaintext, i + 1, 'X') elif i < len(plaintext) - 1 and plaintext[i] == plaintext[i + 1]: plaintext = insert_string(plaintext, i + 1, 'X') digraphs += [plaintext[i:i + 2]] i += 2 ciphertext = str() for digraph in digraphs: #get both chars, their coordinates char1, char2 = list(digraph) row1, column1 = get_coordinates(square, char1) row2, column2 = get_coordinates(square, char2) encoded_row1, encoded_column1 = row1, column1 encoded_row2, encoded_column2 = row2, column2 #apply transformation rules if row1 != row2 and column1 != column2: # making a rectangle - take the other 2 corners, with the same row respectively encoded_row1, encoded_column1 = row1, column2 encoded_row2, encoded_column2 = row2, column1 elif row1 != row2 and column1 == column2: # same column - get the caracter down encoded_row1 = (row1 + 1) % 5 encoded_row2 = (row2 + 1) % 5 elif row1 == row2 and column1 != column2: # same row - get the caracter right encoded_column1 = (column1 + 1) % 5 encoded_column2 = (column2 + 1) % 5 #output resulting chars encoded_char1 = get_char(square, encoded_row1, encoded_column1) encoded_char2 = get_char(square, encoded_row2, encoded_column2) ciphertext += encoded_char1 + encoded_char2 return ciphertext
# #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"