动态计算蛮力大小?

时间:2009-09-23 03:34:32

标签: python math brute-force

如何动态计算蛮力方法的大小?例如,如果您从0:0:0:0:0:0:0:0 - ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff到文件?打印所有IPv6地址将需要多少次迭代和空间?棘手的部分是线长变化的部分。 IP地址仅是示例。

想法是你给出给定部分的格式和最大长度。因此,如果变量类型为'%c'(char),并且maxlen为26,则迭代计数为26,并且文本文件中人类格式所需的空间为26 + 26(分隔符为一个字符)

def calculate(format, rules):

  end = format

  for i in rules:
    (vartype, maxlen) = rules[i]
    end = end.replace(i, vartype % maxlen)


  start = format

  for i in rules:
    (vartype, maxlen) = rules[i]
    minlen = 0
    start = start.replace(i, vartype % minlen)

  start_bytes = len(start)
  end_bytes = len(end)

  # how to add for example IPv4 calculations
  #         0.0.0.0 - 9.9.9.9
  #     10.10.10.10 - 99.99.99.99
  # 100.100.100.100 - 255.255.255.255

  iterations = 0

  for i in rules:
    if format.find(i) is not -1:
      (vartype, maxlen) = rules[i]
      if iterations == 0:
        iterations = int(maxlen) + 1
      else:
        iterations *= int(maxlen) + 1

  iterations -= 1

  needed_space = 0

  if start_bytes == end_bytes:
    # +1 for separator (space / new line)
    needed_space = (1 + start_bytes) * iterations
  else:
    needed_space = "How to calculate?"

  return [iterations, needed_space, start, end, start_bytes, end_bytes]


if __name__ == '__main__':

  # IPv4
  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%d', 255],
      '%b': ['%d', 255],
      '%c': ['%d', 255],
      '%d': ['%d', 255]
    },
  )

  # IPv4 zero filled version
  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%03d', 255],
      '%b': ['%03d', 255],
      '%c': ['%03d', 255],
      '%d': ['%03d', 255]
    },
  )


  # IPv6
  print calculate(
    "%a:%b:%c:%d:%e:%f:%g:%h",
    {
      '%a': ['%x', 65535],
      '%b': ['%x', 65535],
      '%c': ['%x', 65535],
      '%d': ['%x', 65535],
      '%e': ['%x', 65535],
      '%f': ['%x', 65535],
      '%g': ['%x', 65535],
      '%h': ['%x', 65535]
    },
  )

  # days in year, simulate with day numbers
  print calculate(
    "ddm%a", #ddmmyy
    {
      '%a': ['%03d', 365],
    },
  )

例如:

  • 1.2.3.4需要7个字节
  • 9.9.9.10需要8个字节
  • 1.1.1.100需要9个字节
  • 5.7.10.100需要10个字节
  • 128.1.1.1需要9个字节

示例0.0.0.0 - 10.10.10.10:

  iterations = 0
  needed_space = 0

  for a in range(0, 11):
    for b in range(0, 11):
      for c in range(0, 11):
        for d in range(0, 11):
          line = "%d.%d.%d.%d\n" % (a, b, c, d)
          needed_space += len(line)
          iterations += 1

  print "iterations: %d needed_space: %d bytes" % (iterations, needed_space)

迭代:14641 needed_space:122452字节

  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%d', 10],
      '%b': ['%d', 10],
      '%c': ['%d', 10],
      '%d': ['%d', 10]
    },
  )

结果:[14641,122452]

3 个答案:

答案 0 :(得分:4)

使用combinatorics和离散数学:

IPv4地址空间为256 * 256 * 256 * 256 = 2 ^ 32 = 4,294,967,296地址。

IPv6有2 ^ 128个地址(8组16 * 16 * 16 * 16)。

IPv4地址使用32位,因此如果存储,则32位* 4,294,967,296地址= 16 gigabytes 在磁盘上。

IPv6地址使用128位,因此128位* 2 ^ 128地址= 5.07 * 10^30 gigabytes

答案 1 :(得分:0)

首先计算您需要的行数。 IPv6地址为128位,因此输出文件长度为2 128 。如果您的所有行为空,则大约为3.4×10 38 字节。一个太字节只有大约10个 12 字节,所以你需要超过3×10 26 1TB的硬盘才能存储行在将任何数据放入其中之前。

每行存储40个字节需要按比例增加存储空间。

答案 2 :(得分:0)

将其分解成组件可能是要走的路;对于IPv4,你有四个部分,由三个点分隔,每个部分可以是1,2或3个字符(0-9,10-99,100-255)长。所以你的组合是:

comp_length = {1: 10, 2: 90, 3: 156}

您可以通过迭代每个组合来计算总长度:

def ipv4_comp_length(n=4):
    if n == 1:
        return comp_length
    res = {}
    for rest, restcnt in ipv4_comp_length(n-1).iteritems():
        for first, firstcnt in comp_length.iteritems():
             l = first + 1 + rest # "10" + "." + "0.0.127"
             res[l] = res.get(l,0) + (firstcnt * restcnt)
    return res

print sum( l*c for l,c in ipv4_comp_length().iteritems() )

请注意,这不会考虑记录分隔符(“1.2.3.4 1.2.3.5”中的空格)。

扩展到IPv6应该基本上是直截了当的 - 除非您想要处理缩写的IPv6地址,例如0 :: 0 == 0:0:0:0:0:0:0:0。