【问题标题】:Hashing same character multiple times多次散列相同的字符
【发布时间】:2013-04-30 05:51:23
【问题描述】:

我正在做一个编程挑战,其中一个挑战让我发疯了。在挑战中,我需要计算字符串的 MD5。字符串以下列形式给出:

n[c]:其中n 是一个数字,c 是一个字符。例如:b3[a2[c]] => baccaccacc

在我得到以下字符串之前一切正常:

1[2[3[4[5[6[7[8[9[10[11[12[13[a]]]]]]]]]]]]]

这个字符串变成了一个带有 6227020800 a 的字符串。该字符串超过 6GB,因此几乎不可能在实际时间内计算出来。所以,这是我的问题:

我可以在这里使用 MD5 的任何属性吗?

我知道必须有一种形式才能在短时间内完成,我怀疑这必须与所有字符串都是重复多次的相同字符有关。

【问题讨论】:

  • 这可能是简单的反向查找并找到第一个出现的[,将(a)后面的字符替换为[前面的数字(13,所以13*'a') 然后将该字符串放入变量中,查找下一个[ 并取mystoredstring*num 等等..
  • @Torxed 这个问题不是关于从它的紧凑表示中生成实际的字符串(这将是一个 6227020800 时间的字母,正如 OP 已经说过的那样),而是关于有效地计算这样一个大字符串。
  • 我可以在我的机器上用大约 14 秒的 CPU 时间来计算它。你如何定义“实际时间”?
  • @Aya 该死的,我需要 22 秒 :-) 68df0fa...?

标签: python string algorithm hash md5


【解决方案1】:

您可能已经创建了一个(递归)函数来将结果生成为单个值。相反,您应该使用生成器将结果生成为字节流。然后,您可以将这些数据逐字节输入到您的 MD5 哈希例程中。这样流的大小无关紧要,它只会影响计算时间,而不是使用的内存。

这是一个使用单遍解析器的示例:

import re, sys, md5

def p(s, pos, callBack):
  while pos < len(s):
    m = re.match(r'(d+)[', s[pos:])
    if m:  # repetition?
      number = m.group(1)
      for i in range(int(number)):
        endPos = p(s, pos+len(number)+1, callBack)
      pos = endPos
    elif s[pos] == ']':
      return pos + 1
    else:
      callBack(s[pos])
      pos += 1
  return pos + 1

digest = md5.new()
def feed(s):
  digest.update(s)
  sys.stdout.write(s)
  sys.stdout.flush()

end = p(sys.argv[1], 0, feed)
print
print "MD5:", digest.hexdigest()
print "finished parsing input at pos", end

【讨论】:

  • 是的,这就是我一直在寻找的房产。感谢您的宝贵帮助
【解决方案2】:

所有散列函数都设计用于处理字节流,因此您不应该首先生成整个字符串,然后再对其进行散列 - 您应该编写生成器,生成字符串数据块,并将其提供给 MD5 上下文。 而且,MD5 使用 64 字节(或字符)缓冲区,因此最好将 64 字节的数据块提供给上下文。

【讨论】:

    【解决方案3】:

    利用散列的良好特性:

    import hashlib
    cruncher = hashlib.md5()
    chunk = 'a' * 100
    for i in xrange(100000):
        cruncher.update(chunk)
    print cruncher.hexdigest()
    

    调整轮数 (x = 10000) 和块的长度 (y = 100),使 x * y = 13!。关键是你正在用你的字符串块(每个 x 个字符长)一个接一个地为算法提供 y 次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多