【问题标题】:Obfuscated mandlebrot function - can someone deobfuscate it?混淆的 mandlebrot 函数 - 有人可以去混淆它吗?
【发布时间】:2014-08-04 16:53:48
【问题描述】:

我是 python 新手,我对它生成分形图像的能力非常感兴趣。我自己写了一些简单的,但我刚刚发现了一个 Mandelbrot 分形的脚本......它以您想要的分辨率产生美丽的全彩色图像......但是代码被混淆成看起来像 Mandelbrot 的 ASCII 艺术....真的很酷,但如果你想轻松阅读它就很傻。它包含我还没有在 python 中学习过的功能,所以如果有人可以缩进脚本看起来像普通的 python 脚本,那就太好了。 脚本:

_                                      =   (
                                        255,
                                      lambda
                               V       ,B,c
                             :c   and Y(V*V+B,B,  c
                               -1)if(abs(V)<6)else
               (              2+c-4*abs(V)**-0.4)/i
                 )  ;v,      x=7200,4800;C=range(v*x
                  );import  struct;P=struct.pack;M,\
            j  ='<QIIHHHH',open('M.bmp','wb').write
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
            i  ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9
                  *i-950*T  **99,T*70-880*T**18+701*
                 T  **9     ,T*i**(1-T**45*2)))(sum(
               [              Y(0,(A%3/3.+X%v+(X/v+
                               A/3/3.-x/2)/1j)*2.5
                             /x   -2.7,i)**2 for  \
                               A       in C
                                      [:9]])
                                        /9)
                                       )   )

正如我所说,艺术很酷,但太难读了!如果有人能做到这一点,我将不胜感激。

【问题讨论】:

  • 我建议使用PythonTidy
  • 就算整理好了,这个baby身上的内圈也是用了一个很长的表情。
  • 由于混淆的目的是为了混淆和迷惑,因此变量名也很可能没有意义甚至误导。就个人而言,我认为你最好花时间学习计算分形所涉及的数学——这并不难——而不是试图破译这个怪物。
  • 是的,我明白了...我认为提交此文件是为了在尽可能少的行中制作 Mandelbrot...我找到了其他人,但我没有看到使用颜色像这样的渐变。任何人都知道任何可以使Mandelbrots与此非常相似的东西吗? @martineau 你知道他用什么方法来获得颜色渐变吗?如果我知道这一点,我可以相当容易地编写实际的数学位
  • 颜色似乎是前几次迭代值的函数,直接将颜色编码到 BMP 规范中。我会使用 Matplotlib,只需生成一个包含值的数组,然后让颜色图找出其余部分。

标签: python obfuscation fractals deobfuscation


【解决方案1】:

注意:这并不是一个明确的答案,而是一个逐步去混淆的努力。如果您可以提供一个额外的步骤来使事情更清楚,那么如果您可以将其添加到此答案中,那就太好了。

好的,让我们从给代码适当的换行符和缩进开始:

_ = (255,
    lambda V, B, c: c and Y(V*V + B, B, c-1) if(abs(V) < 6) else (2 + c - 4 * abs(V)**-0.4)/i)
v, x = 7200, 4800
C = range(v*x)
import struct
P=struct.pack
M, j = '<QIIHHHH', open('M.bmp','wb').write
for X in j('BM' + P(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
    i, Y = _
    j(
        P('BBB',
                *(lambda T: (T * 80 + T**9 * i - 950 * T**99, T*70 - 880* T**18 + 701* T**9, T* i**(1-T**45*2)))(
                    sum([Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2 for A in C[:9]]) / 9
                )
        )
    )

好一点,但仍然令人困惑。例如,将P 定义为struct.pack 的别名,以及所有这些二合一声明。如果我们摆脱它们,并将 lambda 定义移到循环之外,我们会得到:

import struct
i = 255
Y = lambda V, B, c: c and Y(V*V + B, B, c-1) if(abs(V) < 6) else (2 + c - 4 * abs(V)**-0.4)/i
v = 7200
x = 4800
C = range(v*x)
M = '<QIIHHHH'
color = lambda T: (T * 80 + T**9 * i - 950 * T**99, T*70 - 880* T**18 + 701 * T**9, T * i**(1-T**45*2))

f = open('M.bmp','wb')
for X in f.write('BM' + struct.pack(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
    f.write(
        struct.pack('BBB',
            *color(sum([Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2 for A in C[:9]]) / 9))
    )

现在事情开始变得有点清晰了。循环为每个像素写入颜色值,lambda 返回一个 3 元组,表示每个像素的蓝色、绿色和红色值。

import struct
i = 255
Y = lambda V, B, c: c and Y(V*V + B, B, c-1) if abs(V) < 6 else (
                    (2 + c - 4 * abs(V)**-0.4)/i)
v = 7200
x = 4800
C = range(v*x)
M = '<QIIHHHH'
color = lambda T: (T * 80 + T**9 * i - 950 * T**99,
                   T*70 - 880* T**18 + 701 * T**9,
                   T * i**(1-T**45*2))
f = open('M.bmp', 'wb')
for X in f.write('BM' + struct.pack(M, v*x*3+26, 26, 12, v, x, 1, 24)) or C:
    f.write(struct.pack('BBB',
        *color(sum(
            [Y(0, (A%3/3. + X%v + (X/v + A/3/3. - x/2)/1j) * 2.5/x - 2.7, i)**2
                for A in C[:9]]) / 9))
    )

根据您的评论,the asterisk (the star, *) unpacks a list into an argument list

几个小时后,这是Mandelbrot set 生成的近 100 MB 的图像:

【讨论】:

  • 这样更好...&lt;QIIHHHH 是什么意思?倒数第二行,*color... 星号在做什么?
  • @Lillz struct.pack 将 Python 数字转换为 C 二进制数据的表示形式。 &lt;QIIHHHH 是格式规范,其中&lt; 表示 little-endian,H 表示 unsigned-short int,I 是 unsigned int。 Q 是一个 unsigned long long。
  • Carsten:如果您的回答是一个社区 wiki,其他人可能更倾向于使用它。
  • 啊这肯定更好。我还没有到能看懂 lambda 函数的地步,但能看清楚代码就很棒了。
  • @martineau 这是计划,但我没有注意到按钮,并认为创建社区 wiki 的唯一方法是自动方式,由 5 个人编辑。还有,画面不错。 :)
猜你喜欢
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 2013-03-20
  • 2010-11-01
  • 2014-07-15
  • 2017-03-11
相关资源
最近更新 更多