Generates random Python functions using Markov chains
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

func_smash.py 3.5 KiB

před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import dis
  2. import opcode
  3. import random
  4. import types
  5. ############## CODE ###########################################################
  6. MARKOV_START = -1
  7. MARKOV_END = -2
  8. def make_chain(funcs):
  9. chain = {}
  10. for func in funcs:
  11. co = func.__code__
  12. code = co.co_code
  13. n = len(code)
  14. i = 0
  15. lastop = MARKOV_START
  16. while i < n:
  17. op = ord(code[i])
  18. i += 1
  19. if op >= opcode.HAVE_ARGUMENT:
  20. oparg = ord(code[i]) + ord(code[i + 1]) * 256
  21. i += 2
  22. if op in opcode.hasconst:
  23. arg = co.co_consts[oparg]
  24. elif op in opcode.haslocal:
  25. arg = co.co_varnames[oparg]
  26. elif op in opcode.hascompare:
  27. arg = opcode.cmp_op[oparg]
  28. else:
  29. raise NotImplementedError(op, opcode.opname[op])
  30. else:
  31. arg = None
  32. _chain_append(chain, lastop, (op, arg))
  33. lastop = op
  34. _chain_append(chain, op, MARKOV_END)
  35. return chain
  36. def make_function(chain, name, argcount=1):
  37. codes, constants, varnames = _make_codes(chain)
  38. nlocals = len(varnames) + argcount
  39. stacksize = 1024 # High limit?
  40. flags = 0 # Denotes funcs with *args and/or **kwargs; nothing for now
  41. codestring = "".join([chr(code) for code in codes])
  42. names = ()
  43. filename = "<smash>"
  44. firstlineno = 1
  45. lnotab = ""
  46. code = types.CodeType(argcount, nlocals, stacksize, flags, codestring,
  47. constants, names, varnames, filename, name,
  48. firstlineno, lnotab)
  49. func = types.FunctionType(code, globals(), name)
  50. return func
  51. def _chain_append(chain, first, second):
  52. try:
  53. chain[first].append(second)
  54. except KeyError:
  55. chain[first] = [second]
  56. def _make_codes(chain):
  57. codes = []
  58. code = random.choice(chain[MARKOV_START])
  59. constants, varnames = [], []
  60. while 1:
  61. if code == MARKOV_END:
  62. break
  63. op, arg = code
  64. codes.append(op)
  65. if op >= opcode.HAVE_ARGUMENT:
  66. if op in opcode.hasconst:
  67. if arg not in constants:
  68. constants.append(arg)
  69. args = constants
  70. elif op in opcode.haslocal:
  71. if arg not in varnames:
  72. varnames.append(arg)
  73. args = varnames
  74. elif op in opcode.hascompare:
  75. args = opcode.cmp_op
  76. else:
  77. raise NotImplementedError(op, opcode.opname[op])
  78. codes.append(args.index(arg))
  79. codes.append(0)
  80. code = random.choice(chain[op])
  81. return codes, tuple(constants), tuple(varnames)
  82. ############## FUNCTION CORPUS ################################################
  83. def f1(a):
  84. b = a + 7.0
  85. return b
  86. def f2(a):
  87. b = a - 5.0
  88. return b
  89. def f3(a):
  90. b = a * 3.0
  91. return b
  92. def f4(a):
  93. b = a / 2.0
  94. return b
  95. corpus = [f1, f2, f3, f4]
  96. ############## DEMO ###########################################################
  97. if __name__ == "__main__":
  98. print "USING FUNCTION CORPUS:", [func.__name__ for func in corpus]
  99. chain = make_chain(corpus)
  100. print "OPCODE MARKOV CHAIN:", chain
  101. print
  102. func = make_function(chain, "func")
  103. print "SMASHED FUNCTION CODE:", [ord(c) for c in func.__code__.co_code]
  104. print "FUNCTION DISASSEMBLY:"
  105. dis.dis(func)
  106. print
  107. n = 12.0
  108. print "func(%s) =" % n, func(n)