I have some inputs
inputs = ["and", "dick", "jane", "puff", "spot", "yertle"]
than I have sentence composed from words from inputs encrypted_sentence ="bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn" but letters are changed in some pattern. For example "a"='x'; "n"='s'; "d"='b'.....
Every letter in alphabet is replaced for some different letter in alphabet. I need to create dictionary where new 'letter' will be key and old letter will be value. Like this decrypt_dict={ "x":'a', "s":'n', "b":'d', "q":'a', "t":'t'} and so on... If amount of unique letters in inputs is different from amount of unique letters in sentence, print "ERROR"because it's not possible to create sentence from inputs
If some letters are not used, nevermind, just skip them. It is not necessary to create dict with every char in alphabet, I just need the ones that were used in the encoding
this is my code so far (i used another test strings):
import itertools
def deduplicate(lst):
elems = set()
rest = []
for el in lst:
if el not in elems:
elems.add(el)
rest.append(el)
return rest
def deduplicate_lists(lst_of_lists, differenet_lists=False):
lst_of_lists.sort()
if differenet_lists:
return [lst for lst, _ in itertools.groupby(lst_of_lists)]
else:
return [*[lst for lst, _ in itertools.groupby(lst_of_lists)]]
def try_it_faster(lists_by_len_of_words, decrypt_dict):
for key, val in lists_by_len_of_words.items():
# print(ke, val)
if len(val) == 1:
for index, char in enumerate(val[0]):
# print(char, index_for_word)
decrypt_dict.update({char: key[index]})
return decrypt_dict
def decrypt(string_to_decrypt, decrypt_dict):
returner = None
try:
returner = "".join(decrypt_dict[i] for i in string_to_decrypt)
except KeyError:
pass
return returner
def c_just_multiple_val_dict(dict, help_dict=None):
copy_dict = dict.copy()
for keys, values in copy_dict.items():
# print(keys, values)
if len(values) == 1:
dict.pop(keys)
if help_dict is not None:
copy_dict = dict.copy()
for word in copy_dict.keys():
if all([char in help_dict.values() for char in word]):
dict.pop(word)
return dict
def move_items(lst):
return lst[0:] + lst[0]
# timed
number = 6
inputs = ['all', 'and', 'apple', 'ass', 'gibble', 'horror', 'hound', 'love',
'tie'] # input words default: "and", "dick", "jane", "puff", "spot", "yertle"
decrypt_dict = {' ': ' '}
encryption_as_string = "cvvli euynm dxggli euzzuz cnm bxi lupi cll cww" # default: bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
encryption_key = encryption_as_string.split() # create list from encrypted string
lists_by_len_of_words = {inp: deduplicate([a for a in encryption_key if len(a) == len(inp)]) for inp in
inputs} # dict key=input word, deduplicated value=words from encryption_key with same length as input word
# timed
# print start values
print(f"1. {inputs}")
print(f"2. {encryption_key}")
print(f"3. {lists_by_len_of_words}")
print(f"4. {decrypt_dict}")
decrypt_dict = try_it_faster(lists_by_len_of_words,
decrypt_dict) # if len of input words is unique, this will make it faster
secondary_decrypt_dict = decrypt_dict.copy()
print(f"4. After try_it_faster(): {decrypt_dict}")
# same_len_word_list = [word for word in lists_by_len_of_words.keys()]
inputs_sorted = sorted(inputs, key=len) # input sorted
inputs_as_string = " ".join(inputs_sorted) # sorted input to string
encryption_key_deduplicated_sorted = sorted(deduplicate(encryption_key),
key=len) # encryption_key sorted and deduplicated
encryption_key_as_string = " ".join(encryption_key_deduplicated_sorted) # sorted encryption_key to string
# print sorted and deduplicated start values
print(f"1. Sorted input words as string: {inputs_as_string}")
print(f"2. Sorted and deduplicated encrypted words as list: {encryption_key_deduplicated_sorted}")
print(f"2. Sorted and deduplicated encrypted words as string: {encryption_key_as_string}")
mover_check = len(encryption_key_deduplicated_sorted)#*len(encryption_key_deduplicated_sorted)
mover = 0
# while decrypt(encryption_key_as_string, secondary_decrypt_dict) != inputs_as_string:
while decrypt(encryption_key_as_string, secondary_decrypt_dict) != inputs_as_string and mover < mover_check:
print(f"Before clearing:{encryption_key_deduplicated_sorted}")
for index_of_word, input_word in enumerate(inputs_sorted):
print(index_of_word, input_word,
decrypt(encryption_key_deduplicated_sorted[index_of_word], secondary_decrypt_dict))
if decrypt(encryption_key_deduplicated_sorted[index_of_word], secondary_decrypt_dict) == input_word:
for index_of_char, char in enumerate(encryption_key_deduplicated_sorted[index_of_word]):
# print(index_of_char, char)
decrypt_dict[char] = input_word[index_of_char]
print(f"pop out {inputs_sorted[index_of_word]} a {encryption_key_deduplicated_sorted[index_of_word]}")
inputs_sorted.pop(index_of_word)
encryption_key_deduplicated_sorted.pop(index_of_word)
print(f"After clearing:{encryption_key_deduplicated_sorted}")
print(f"Work wi :{inputs_sorted}")
secondary_decrypt_dict.clear()
secondary_decrypt_dict.update(decrypt_dict)
# secondary_decrypt_dict.update(decrypt_dict)
# print(encryption_key_deduplicated_sorted)
for index_for_word, encryption_word in enumerate(encryption_key_deduplicated_sorted):
print(index_for_word, encryption_word)
for index_for_char, letter in enumerate(encryption_word):
# print(letter)
if secondary_decrypt_dict.get(letter) is None:
print(f"secondary_dict nor contain:{letter}")
if decrypt_dict.
try:
print("".join(char for char in inputs_sorted[index_for_word])[index_for_char])
secondary_decrypt_dict.update(
{letter: "".join(char for char in inputs_sorted[index_for_word])[index_for_char]})
setter = False
# print(secondary_decrypt_dict)
except IndexError:
setter = True
else:
# pass
setter = False
print(f"Contains:{letter}")
encryption_key_deduplicated_sorted = encryption_key_deduplicated_sorted[1:] + encryption_key_deduplicated_sorted[:1]
if setter:
sorted(encryption_key_deduplicated_sorted, key=len)
print(decrypt(encryption_key_as_string, secondary_decrypt_dict))
mover += 1
print(secondary_decrypt_dict)
print(decrypt_dict)
final_dict = {**secondary_decrypt_dict, **decrypt_dict}
print(final_dict)
str = "cvvli euynm acqyg dxggli euzzuz cnm bxi lupi cll cww"
if decrypt(str, final_dict) is None:
ret_str = ""
for char in encryption_key_as_string:
if char != " ":
ret_str.__add__(char)
else:
ret_str.__add__(" ")
print(ret_str)
else:
print(decrypt(str, final_dict))