【问题标题】:Best approaches to use to guess a a string of a certain length under certain conditions在特定条件下猜测特定长度字符串的最佳方法
【发布时间】:2020-08-28 06:01:45
【问题描述】:

我一直在从事一项休闲代码挑战,其中我需要成功生成一串数字(长度为 32 个字符,数字 0-9,能够重复),该字符串与我不知道的值相匹配。起初我建立了一个蛮力解决方案,但不仅基本上不可能用 10^32 的可能性做出任何有意义的猜测,还有时间限制(12 秒)和在该时间跨度内通过多个测试(10 个测试每个人都有不同的密码)。

是否有我可以研究的具体方法实际上可以解决这个问题?

这是我最初的蛮力解决方案,但我几乎放弃了使用蛮力解决方案的想法:

const carryRemainder = (code, index = 31) => {
  if (code[index] === "9") {
    return index === 0 ? carryRemainder(code, 31) : carryRemainder(code, index - 1);
  }
  
  const newCode = `${code.slice(0, index)}${Number(code[index]) + 1}${"0".repeat(31 - index)}`;
  
  return newCode;
}

function crack(login) {
  let code = '00000000000000000000000000000000';
  
  while (!login(code)) {
    code = carryRemainder(code);
  }
  
  return code;
}

有问题的挑战:

https://www.codewars.com/kata/59ae7edbba7b60c17500006e/train/javascript

【问题讨论】:

  • 是否存在您不知道的值的限制或特征?没有更多信息,这里最好的只是蛮力。
  • 你可以使用类似(parseInt(code, 10) + 1).toString().padStart(32, '0')的东西来提高carryRemainder函数的效率
  • @ManishHonnatti 我怀疑挑战描述中可能隐藏了一些对我有帮助的东西,我不想直接链接到挑战,因为我的目标不仅仅是让某人回答问题我,但如果这能提供更多洞察力,我会的。
  • @Titus 我担心可能性的数量是如此之多,以至于没有对蛮力进行优化是有意义的。
  • @CoryHarper 公平点。

标签: javascript algorithm cryptography


【解决方案1】:

蛮力不是一个可行的解决方案:1032 比人体中的原子还多。

您可以使用的一个信息是:黑盒验证器需要多少时间来告诉您猜测是对还是错?

如果那个验证器设计得不是很好,它可能看起来像这样:

for (let i = 0; i < 32; i++) {
    if (secret[i] != guess[i]) return false;
}
return true;

这可能看起来像是一个非常明显的实现(在那个黑盒中),但它有一个漏洞:正确的字符越多(作为前缀),它将执行的迭代越多。所以这给了黑客一些信息。

他们可以计算执行时间,看看对于一个特定的 first 字符,平均而言,执行时间是否会稍微长一点。如果经过多次运行,很明显一个角色脱颖而出,他们可以假设它是正确的,并对第二个角色重复相同的过程,依此类推。这是side-channel attack 的一种变体。

由于执行时间总是有一个可变的组成部分,由于计算机上发生的其他事情、动态执行优化(典型的 JavaScript 引擎)、垃圾收集等,在得出结论之前运行足够的样本很重要,但是当黑盒实现的设计如上时,它肯定是这样做的。

【讨论】:

  • 黑盒的设计类似,但它使用 javascript 的 every 数组方法来执行与您的示例相同的比较。如何在不访问黑匣子的情况下为特定迭代计时?
  • 您可以使用performance API。 NodeJS 也有process.hrtime。只需将时间之前验证调用,然后将其抵消调用之后的时间。但是对于“通话”,我真的是指 1000 次通话,否则经过的时间将太小。
  • 我对在 CodeWars 上看到这个挑战有一个模糊的记忆。如果你有参考,我可以看看我是如何解决的。
  • 好的,我知道我过去解决了那个问题。我看到我实际上使用了process.hrtime,而且我首先进行了试运行,看看我可以在 0.01 秒内调用多少次login 函数(传递一个空字符串),并实施了一些双重检查以确保某些字母确实是最佳选择,...等等。这真是一个谜。祝你好运!
猜你喜欢
  • 2013-08-21
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 2016-11-11
相关资源
最近更新 更多