exppad* / blog / Obfuscated Python Bunny Calligram

Obfuscated Python Bunny Calligram

A bunny shaped Python code generating a bunny!

A while ago, I bumped into this amazing obfuscated python script generating a Mandelbrot fractal while being itself shaped like its render, and loved it. It is a true calligram in code. And the most impressive to me was that it was done in Python! Since white spaces and line breaks do have a meaning in Python, one is not really free to shape the code at will.

So I took the idea and did my own version. This is a ray tracer, which I got to trace a stanford bunny:

Obfuscated Python Bunny Calligram

#!/usr/bin/python3
# Copyright (c) 2018 -- Élie Michel
import struct
import math



(                            lambda
          A,M,             e,p,U,b,
         w,h:(          lambda o,lt,S
         ,X,D,nz      ,wv,F,P:(lambda
         z:(lambda   b1: (lambda b2:(
          F(b'BM'  +P('<QIIHHHH',w*
           h*3+26,26,12,w,h,1,
        24)) and 0)or[F(P(
      'BBB',wv(p[2]),wv(
      p[1]),wv(p[0])))
      for p in[(lambda y
      :(lambda s:(200,200,
      255)if not s else[M(           r[2],abs(p(
      r[1],y)))for r in s if r[0]==min([r[0]for r in
     s])][0])(list(filter (None, [(lambda v1,v2,x,s:(
     lambda d:(d or None) and (lambda a,b,c:((a>=0 and b
      >=0 and a+b<=1 and c<=0)or None)and(-c,nz(X(v1,v2))
        ,t[3]))(s(x,v2,y)/d,s(v1,x,y)/d,s(v1, v2,x)/d))(s(
        v1,v2,y)))(D(t[1],t[0]), D(t[2],t[0]), (D(o,t[0])),
       lambda a,b,c:(a[0]*(b[1]*c[2]-c[1]*b[2])-b[0]*(a[1]*
       c[2]-c[1]*a[2])+c[0]*(a[1]*b[2]-b[1]*a[2])))for t in
        S]))))(nz(A(z,A(M(b1,(w/2-x)*10./w),M(b2,(y-h/2)*10/
        w))))) for y in range(h) for x in range(w)]])(nz(X(z
        ,b1))))(e(0)if z==e(2)else nz(X(e(2),z))))(D(lt,o)))(U(
         '<fff',b),U('fff',b,12),[(t[:3],t[3:6],t[6:9],t[9:])for
          t in struct.iter_unpack('fffffffffBBB',b[24:])], lambda
            a,b:(a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2],a[0]*b[
              1]-a[1]*b[0]),lambda a,b: A(a,(-b[0],-b[1],-b[2])),
                 lambda a:M(a,1/math.sqrt(p(a,a)))if a!=e(3)else
                    a, lambda x:min(max(int(x), 0), 255), open(
                  'S.bmp','wb').write,struct.pack))(lambda a,
                b:(a[0]+b[0],a[1]+b[1],a[2]+b[2]),lambda a,
               v:(a[0]*v,a[1]*v,a[2]*v),lambda i:(+(i==0),
              +(i==1),+(i==2)),lambda a,b:a[0]*b[0]+a[
                 1]*b[1]+a[2]*b[2],struct.unpack_from
                  ,open('S.bin','rb').read(),800,600)

I have to admit that contrary to the Mandelbrot code, this one does not stand alone. It is actually a generic raytracer, which requires a S.bin file as input to describe the scene to render. You can generate this file from Blender, using the following snippet:

import bpy
import struct

f = open("/tmp/S.bin", "wb")

f.write(struct.pack("<ffffff", -10, -10, 2, 0, 0, 0))

def tri(p0, p1, p2, c):
    f.write(struct.pack("<fffffffffBBB", p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], c[0], c[1], c[2]))

red = (255, 0, 0)

for obj in bpy.context.selected_objects:
    d = obj.data
    for p in d.polygons:
        v = lambda i: d.vertices[d.loops[p.loop_start + i].vertex_index].co
        tri(v(0), v(1), v(2), red)

f.close()

You must select the object to export, apply all transforms with Ctrl+A, then run the script. As an example, here is the bunny scene S.bin as well as a simplified version rendering faster S.bin. Also, you may want to start with a much lower resolution, because this code is veeery slow. It took 3h10 to my i5 processor to render the high-poly bunny in 800x600. Here is the exact output: S.bmp.

Article publié le 11 Avril 2018 par Élie

Élie Michel


Réactions

Pas de réactions

In order to react, you are invited to use Webmentions or to contact me on Twitter.