Как решить задачу вычисления, а затем проверки 10 ^ 8 решений, чтобы найти один правильный ответ?

#python #gmpy

#python #gmpy

Вопрос:

У меня есть число длиной 615 цифр. Во всем числе есть 8 фиксированных мест, где отсутствует цифра. Я должен найти, что это за недостающие цифры. Итак, существует 10 ^ 8 возможностей. После их вычисления я должен создать шифротекст для каждого возможного числа и посмотреть, каков результат (mod N), и посмотреть, какое число дает правильный результат. Другими словами, я пытаюсь найти ключ дешифрования в задаче RSA. Моя главная задача сейчас — как эффективно / правильно создать все 10 ^ 8 возможных ответов.

Я использую gmpy2, и чтобы заставить это работать, мне пришлось загрузить Python2.7, чтобы не получить ошибку при попытке установить gmpy2. Я надеюсь, что они достаточно адекватны для решения этой проблемы. Если нет, я был бы очень признателен, если бы кто-нибудь указал мне правильное направление.

Я еще ничего не пробовал, так как уверен, что на вычисления уйдут часы. Поэтому я действительно хочу убедиться, что я все делаю правильно, чтобы, если я позволю своему ноутбуку работать пару часов, я не испортил внутренности, и он не зависнет, и я буду сидеть здесь, не зная, испортился ли мой ноутбук, или он все еще вычисляет.

Итак, я полагаю, я пытаюсь получить совет о том, как мне действовать дальше.

С точки зрения фактического кода, я полагаю, что повторение 0-9 8 раз не так сложно, но я не знаю, как преобразовать число в другое число. Как мне сделать так, чтобы число вставлялось только в ту позицию, в которой оно мне нужно? Число выглядит следующим образом:

 X = 124621431523_13532535_62635292 //this is only 30 digits long, mine is 615 digits long
  

где каждое «_» — это то, где отсутствует число.

Я совершенно не понимаю, как это сделать.

Как только все числа сгенерированы, я намерен перебирать их все и увеличивать их, пока не получу требуемый ответ. Эта часть кажется немного проще, так как кажется, что это просто простой цикл.

Итак, я предполагаю, что мой главный вопрос заключается в том, как перебирать 10 ^ 8 чисел, но помещать их в определенное место внутри числа, длина которого уже составляет 615 цифр? Я ищу совета как по техническому, так и по дизайну кода, чтобы не занимать слишком много времени для их создания.

Спасибо за чтение.

Комментарии:

1. Знаете ли вы, в какой момент число «отсутствует». Если вы это сделаете, вы можете предположить, что эти цифры равны нулю. Затем создайте массив arr длиной 8. N-й элемент массива — это число в диапазоне от 0 до 9, которое вы хотите опробовать на N-й цифре. Если N-я цифра находится в позиции M, то X = X 10 ^ M, где M считается как 0 от наименее значащей цифры. Затем вам нужно сгенерировать все возможные перестановки arr, перебрать их и проверить, решает ли это шифр

2. Ключ в том, что это x**(a b) mod N можно учесть x**a * x**b mod N , поэтому вам нужно только сделать один с нулями, которые являются a, а затем выполнить некоторую работу для каждого из bs

Ответ №1:

Превратите число в строку, используйте format метод, используйте itertools.product для генерации чисел, чтобы заполнить пробелы, затем верните его обратно.

Пример:

 from itertools import product

def make_seed(n, replace_positions):
    seed = str(n)
    to_replace = [-1]   replace_positions
    substrings = [seed[start   1:end] 
                  for start, end 
                  in zip(to_replace, to_replace[1:])]   [seed[to_replace[-1]   1:]]
    return '{}'.join(substrings)

def make_number(seed):
    n = seed.count('{}')
    for numbers in product([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], repeat=n):
        yield int(seed.format(*numbers))


seed = make_seed(123456789, [3, 5, 7])
# seed = '123{}5{}7{}9'

for i in make_number(seed):
    print(i)
  

Вывод:

 123050709
123050719
123050729
123050739
123050749
123050759
123050769
123050779
123050789
123050799
123051709
123051719
123051729
...
  

Комментарии:

1. Спасибо. Как вы думаете, сколько времени потребуется для числа длиной 615 цифр, в котором не хватает 8 чисел?

2. Для генерации чисел? Вероятно, не менее часа.

3. Могу я спросить, почему вы подчеркнули «генерировать»? Как вы думаете, сколько времени потребуется для генерации, выполнения проверки, а затем перехода к следующему числу?

4. Могу ли я спросить, как вы могли бы изменить это, чтобы я мог запускать его в разных точках? например, сгенерировать число из 0-10 000 000, затем другое из 10 000 000-20 000 000, чтобы я мог запускать их одновременно? Bc на данный момент, запуск с 0-100 000 000 займет у меня несколько дней.

5. О времени выполнения: бьет меня, но вы, вероятно, могли бы выполнить простое профилирование времени. О запуске: я полагаю, вы могли бы назначить генератор переменной и использовать другой цикл с yield from ?

Ответ №2:

Поскольку десятичная цифра — это просто суммирование digit * pow(10, n) , вы можете считать неизвестные цифры равными нулю и добавить их с помощью цифровых продуктов

 #   124621431523_13532535_62635292 this is the original digit
x = 124621431523013532535062635292
positions = [8,17] # the missing digits are the 8th and 17th digits from the right

from itertools import product
trials = product(range(0,10), repeat=2)
for t in trials:
    x_prime = x
    for (digit, pos) in zip(t, positions):
        x_prime = x_prime   digit * pow(10, pos)
    print(x_prime) # do your checking here

  

выводит:

 124621431523013532535062635292
124621431523113532535062635292
124621431523213532535062635292
124621431523313532535062635292
...
etc
  

Комментарии:

1. да, это будет repeat = 8. По сути product , это предоставить вам поток десятичных цифр длиной N, где N — количество пропущенных цифр

2. Если бы я изменил это на 8 неизвестных, изменил бы я «repeat = 2» на «repeate = 8»? Я также изменил оператор print на оператор if, который будет печатать число, а затем прерывать. Я запускаю это с этими поправками прямо сейчас, и прошло 2 часа. Существуют ли какие-либо другие поправки для 8 неизвестных?

3. кстати, обратите внимание, что это похоже на очень наивный подход к перечислению. Может быть более оптимизированный подход, который не требует перечисления всего пространства ответов 10 ^ 8.