Question

I'm trying to take apart and de-obfuscate this mandlebrot-generating python code:

_                                      =   (
                                        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=1500,1000;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)
                                       )   )

source: http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python/
I found a for loop with an interesting twist, and I'm not sure if it's just part of the obfuscation, or if it actually has a function. The middle line:
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
What does the or do at the end?

I re-wrote the code as follows for clarity:

import struct

image_name = "M.bmp"
mandlebrot = 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
y,x = 600,800
pixelrange = range(y*x)
package = struct.pack

image = open(image_name,'wb').write

for X in image('BM'+package('<QIIHHHH',y*x*3+26,26,12,y,x,1,24)) or pixelrange:
  i = 255
  Y = mandlebrot
  image(package('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%y+(X/y+A/3/3.-x/2)/1j)*2.5/x-2.7,i)**2 for A in pixelrange [:9]])/9)))
Was it helpful?

Solution

Doing:

for x in y or z:

is the same as:

for x in (y or z):

If y evaluates to True, the for-loop will iterate through it. Otherwise, it will iterate through z.

Below is a demonstration:

>>> y = [1, 2, 3]
>>> z = [4, 5, 6]
>>> for x in y or z:
...     print x
...
1
2
3
>>> y = [] # Empty lists evaluate to False in Python
>>> for x in y or z:
...     print x
...
4
5
6
>>>

OTHER TIPS

or returns the first operand if it is boolean true, otherwise the second. Boolean false basically means 0, False, None, or an "empty object" (empty string, list, etc.); boolean true is everything else. So j('BM'+P(M,v*x*3+26,26,12,v,x,1,24)) or C will evaluate to the result of the j(...) call if that result is nonempty, otherwise to C. So it will iterate over the result of j(...) if that result is nonempty, otherwise it will iterate over C.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top