【问题标题】:How to tackle calculating then verifying 10^8 solutions to find the one true answer?如何解决计算然后验证 10^8 个解决方案以找到一个真正的答案?
【发布时间】:2019-04-10 14:51:59
【问题描述】:

我有一个长度为 615 位的号码。在整个数字中,有 8 个固定位置缺少一个数字。我必须找出那些缺失的数字是什么。所以有 10^8 种可能性。在计算它们之后,我必须为每个可能的数字提出一个密文,并查看输出是什么(mod N),并查看哪个数字给出了正确的输出。换句话说,我试图在 RSA 问题中找到解密密钥。我现在主要关心的是如何有效/正确地创建所有 10^8 个可能的答案。

我正在使用 gmpy2,为了让它工作,我必须下载 Python2.7,以免在尝试安装 gmpy2 时出错。我希望它们足以解决这个问题。如果没有,我将非常感谢有人指出我正确的方向。

我还没有尝试过任何东西,因为我确信这需要几个小时来计算。所以我真的想确保我做的一切都是正确的,这样如果我让我的笔记本电脑运行几个小时,我不会弄乱内部,也不会冻结,我会坐在这里不知道我的笔记本电脑是否搞砸了,或者如果它仍在计算。

所以我想我正在尝试就如何进一步进行寻求建议。

就实际代码而言,我认为循环 0-9 8 次并不难,但我不知道如何将一个数字转换为另一个数字。在 Python 中,如何使数字仅插入到我需要的位置?数字看起来像这个例子:

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

每个“_”是缺少数字的地方。

我完全不知道如何做到这一点。

一旦生成了所有数字,我的目标是遍历它们并提高它们,直到我得到所需的答案。这部分似乎更容易一些,因为它看起来只是一个简单的循环。

所以我想我的主要问题是如何循环遍历 10^8 个数字,但将它们放置在一个已经 615 位长的数字内的特定位置?我正在寻求技术和代码设计方面的建议,以免花费太长时间来生成它们。

感谢您的阅读。

【问题讨论】:

  • 你知道数字在哪一点“缺失”。如果这样做,您可以假设这些数字为零。然后创建一个长度为 8 的数组arr。数组的第 N 个元素是您想要在第 N 位上尝试的 0-9 之间的数字。如果第 N 位在位置 M,则 X = X + 10^M 其中 M 从最低有效位开始计为 0。然后你需要生成所有可能的 arr 排列,遍历它们,并检查它是否解决了密码
  • 关键是x**(a+b) mod N 可以分解为x**a * x**b mod N,所以你只需要做一个带零的a,然后为每个bs做一些工作

标签: python gmpy


【解决方案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
...

【讨论】:

  • 谢谢。您认为一个 615 位长但缺少 8 个数字的号码需要多长时间?
  • 生成数字?可能至少几个小时。
  • 我能问一下您为什么强调“生成”吗?您认为它会生成多长时间,进行检查,然后继续下一个数字?
  • 请问您将如何修改它以便我可以在不同的点启动它?例如从 0-10,000,000 生成数字,然后从 10,000,000-20,000,000 生成另一个数字,以便我可以同时运行它们? Bc 目前,从 0 到 100,000,000 对我来说需要几天时间。
  • 关于运行时间:击败我,但您可能可以做一些简单的时间分析。关于运行:我想您可以将生成器分配给一个变量并使用 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

【讨论】:

  • 是的,它会重复=8。基本上product 是给你一个长度为 N 的十进制数字流,其中 N 是丢失数字的数量
  • 如果我把这个修改为 8 unknown,我会不会把“repeat=2”改成“repeate=8”?我还将打印语句更改为 if 语句,它将打印数字然后中断。我现在正在用这些修正来运行它,已经 2 小时了。 8个未知数还有其他修正吗?
  • 顺便说一句,请注意,这感觉像是一种非常幼稚的枚举方法。可能有一种更优化的方法,不需要枚举整个 10^8 答案空间。
猜你喜欢
  • 2016-10-29
  • 2012-03-31
  • 2019-05-11
  • 2021-05-20
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多