random.shuffle с индексацией

Поставил себе задачу сделать типа обфускатора. В общем, пользователь задаёт строку(текст) в переменную text_to_compile. Строка будет например: привет

После чего, программа должна выдать две строки. В первой строке будет перемешанные буквы, к которым нужно будет обратиться со второй строки.

out1 = ['и', 'п', 'р', 'е', 'т', 'в']
out2 = out1[2]..out1[3]..out1[1]..out1[6]..out1[4]..out1[5]

Таким образом, если мы будем обращаться к строке out2, то по индексу будет создана строка, равная строке ввода, т.е. 'привет'.

Пытался сделать сначала так: получаем строку, переводим её в список, получаем индекс каждого символа, из полученных данных индекса и буквы делаем отдельный список который перемешиваем. с перемешанным списком уже ведём работу, но увы, индекс отображается неверно, из за рандома. направление верное, но не совсем понятное.

Может можно как то попробовать сделать через цикл for с максимальным значением длины строки, и каждый раз присваивать новый индекс символу с помощью рандома и отсутствия совпадений, не знаю пока.

import random

text_to_compile = input('Введите текст для шифрования: ')


if text_to_compile:
    text_compiled = list(text_to_compile)

    finished_text = []
    number = 0

    for index in text_compiled:
        number = number + 1
        for k, v in enumerate(index):
            finished_text.append(f'out1[{number}]')

    random.shuffle(text_compiled)
    complete_text = 'local out1 = ' + '..'.join(finished_text)
    complete_text2 = 'local out2 = ' + '..'.join(finished_text)

    print(text_compiled)
    print(complete_text)

Ответы (2 шт):

Автор решения: insolor
import random

input_string = 'привет'

# 1. Берем строку, каждому символу сопоставляем его индекс, вместе с индексами перемешиваем (так мы будем знать исходные индексы):
out = list(enumerate(input_string))
random.shuffle(out)

out1 = [c for i, c in out]  # Список букв
print(out1)  # ['р', 'и', 'т', 'е', 'в', 'п']
out2 = [i for i, c in out]  # Список индексов каждой буквы в исходной строке
print(out2)  # [1, 2, 5, 4, 3, 0]

# 2. Для списка индексов для каждого элемента добавляем его индекс в данном списке,
# создаем словарь, в котором сопоставляем исходному индексу индекс результата:
out3 = {j: i for i, j in enumerate(out2)}
print(out3)  # {1: 0, 2: 1, 5: 2, 4: 3, 3: 4, 0: 5}

# 3. Идем по словарю в порядке возрастания ключа (через range), вытаскиваем значения в отдельный список:
out4 = [out3[i] for i in range(len(out3))]
print(out4)  # [5, 0, 1, 4, 3, 2]

# 4. По индексам получаем буквы в порядке до перемешивания:
out5 = [out1[i] for i in out4]
print(out5)  # ['п', 'р', 'и', 'в', 'е', 'т']

Некоторые пункты можно объединить, но для понятности оставляю так.

UPD. Немного доработал, сортировку заменил на складывание пар индексов в словарь.

→ Ссылка
Автор решения: Stanislav Volodarskiy

Строим перестановку. Затем применяем её к строке.

import random


def cipher(text):
    indices = list(range(len(text)))
    random.shuffle(indices)
    letters = [None] * len(text)
    for j, i in enumerate(indices):
        letters[i] = text[j]
    return letters, '..'.join(str(i + 1) for i in indices)


print(cipher('привет'))

В итоге получается так:

(['р', 'т', 'в', 'п', 'и', 'е'], '4..1..5..3..6..2')
(['п', 'в', 'р', 'т', 'е', 'и'], '1..3..6..2..5..4')
(['и', 'т', 'е', 'р', 'п', 'в'], '5..4..1..6..3..2')
→ Ссылка