Как вызвать значение индекса из перестановки itertools без преобразования его в список? - PullRequest
0 голосов
/ 10 апреля 2020

Мне нужно создать все комбинации этих символов:

'0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM. '

Длина 100 букв, например:

'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'

В настоящее время я использую этот код:

import itertools
babel = itertools.product(k_c, repeat = 100)

Этот код работает, но мне нужно иметь возможность возвращать комбинацию по определенному индексу, однако itertools.product не поддерживает индексирование, превращение продукта в список приводит к ошибке MemoryError и итерации по продукту пока я не достигну определенного значения, для значений свыше миллиарда потребуется слишком много времени.

Спасибо за любую помощь

1 Ответ

0 голосов
/ 10 апреля 2020

С 64 символами и 100 буквами будет 64 ^ 100 комбинаций. Для каждого значения первой буквы будет 64 ^ 99 комбинаций оставшихся букв, затем 64 ^ 98, 64 ^ 97 и т. Д.

Это означает, что ваша N-я комбинация может быть выражена как N в базе 64, где каждый «di git» представляет индекс буквы в строке.

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

chars = '0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM. '

def comboNumber(n,size=100):
    if size == 1: return chars[n]
    return comboNumber(n//len(chars),size-1)+chars[n%len(chars)]

output:

c = comboNumber(123456789000000000000000000000000000000000000123456789)
print(c)
# 000000000000000000000000000000000000000000000000000000000000000000000059.90jDxZuy6drpQdWATyZ8007dNJs


c = comboNumber(1083232247617211325080159061900470944719547986644358934)
print(c)
# 0000000000000000000000000000000000000000000000000000000000000000000000Python.Person says Hello World

И наоборот, если вы хотите узнать, в каком индексе комбинации находится конкретная строка, вы можете вычислить значение base64, комбинируя индекс символа (di git) в каждой позиции:

s = "Python.Person says Hello World" # leading zeroes are implied
i = 0
for c in s:
    i = i*len(chars)+chars.index(c)
print(i) # 1083232247617211325080159061900470944719547986644358934

Теперь вы намного ближе к пониманию кодировки base64, которая аналогична применяемой к 24-битным числам, закодированным в 4 символа (т. Е. 3 двоичных байта -> 4 буквенных числа c символов) или в любом их варианте

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...