Obfuscated Python

What good is a programming language that you cannot obfuscate ? See. So, for your pleasure, here are some obfuscated Python treats.

A Brainf*ck interpreter

Python can run Brainf*ck programs with the help of this little interpreter:

import sys

z,x,y= "}{|}A|k{|kA|}=BE1)|BF}))|$}:~pI~/;@Go{H%{&A?|if }:~pJ"\
       "IJ-1~#>=0:GoAG@HG;o{G;%-I&{?|m,kJ,j=C?;/@~o{~D:Gl[c]("\
       ")?","G$p:%~;%~;el!]':p%break~;![':p%#<len(j):~%\n\t\t"\
       "%if c=='%while o%\n%m[k]%+=1%\t%if not %c=j[o]%-=1%sy"\
       "s.std%[0]*64000,0,0,open(sys.argv[1]).read()%if l.has"\
       "_key(c)%in.read(%out.write(chr(%=1%,o".split('%'),"HG"\
       "&%/~!#?}{;$@ABCDEFIJ"

for i in range(len(x)):z=z.replace(y[i],x[i])
z=z.split('|')
for o in range(9):
    exec("def %c():\n\tglobal k,m,o,j\n\t%s\n"%(chr(97+o),z[o]))
l={'>':c,'<':d,'-': b,'+':a,',':e,'.':f,'[':g,']':h}
i()

Download here.

Just a small quine

A quine is a program that is self-reproducing. That is, the output of the program is the program sourcecode itself. I use the brainfuck interpreter in my very first Python Quine.

Fibonacci and Prime-Number-Detection

With the change in scoping rules in Python 2.2, lambda expressions became much more fun. Here is a function that calculates n fibonacci numbers:

fibonacci = lambda x:map(lambda o:(map(lambda c:map(lambda l:
o.__setslice__(l[0],l[1],l[2]),([o[2]+3,o[2]+4,[o[0]]],[0,3,[o[1],
reduce(lambda x,o:x+o,o[:2]),o[2]+1]])),range(x)),o)[1],[[1,1,0]+
range(x)])[0][3:]

print fibonacci(20)

And in case you need prime numbers, why not use

primes = lambda o:map(lambda a:filter(None,(map(lambda i:map(
lambda x:a.__setitem__(x,0),
range(2*i,o,i)),range(2,o)),a)[1])[1:],[range(o)])[0]

print primes(20)

Matrix Fun

for n in range(12):
    exec("abcdefghijkl"[n]+"=lambda x=0,y=0: "+filter(
        lambda x:x not in "\n$\r","""(x*y#x/x!range(x,
y#x+y!b(1,1#d(e~,e~#d(f~,f~#c(e~,e~+d(g~,d(g~,g~))#"%4
d" % a(x,y#map(lambda y:i(x,y),h~#" ".join(j(x)#"\\n".
join(map(k,h~))""".replace("~","()").replace("#",")!")
        ).split("!")[n])
print l()

A JUSTIF interpreter

Download an uglified version of a JUSTIF interpreter here.

A UNBABTIZED interpreter

Download an uglified version of a UNBABTIZED interpreter here.

Quicksort

My goal when writing the following algorithm was to produce the worlds slowest Quicksort implementation in Python. On my machine (a Dual PIII 1Ghz with 512 mb Ram) sorting 2000 elements with a standard implementation of the algorithm takes 0.08 sec. Sorting them with the following python code takes ... TADA ... 151.68 seconds = 2 minutes, 31 seconds.

import sys

funcs = range(10)

def A(_,o):
    _[3]=_[5]()

def B(_,o):
    o[_[2]]=_[9]()

def C(_,o):
    _[3]=_[7]()

def D(_,o):
    o[_[1]]=_[14]()

def E(_,o):
    _[1]=_[4]()

def F(_,o):
    _[2]=_[6]()

def G(_,o,O):
    if _[O[0]]():return O[-1](_,o) or 1

def H(o, start, stop):
    _=[o[stop],[lambda x,y:x+y,lambda x,y:x-y,lambda x,
                y:y|1,0,0][1](start,funcs[4](range(funcs[3](),
                len(o[:])))),stop,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

    for i in range(4,19):
        _[i]=lambda _=_,o=o,s="reduce([lambda x,y:x+y,lambda "\
              "x,y:x-y,lambda x,y:y|1,0,0][0],[_[1],funcs[4]("\
              "range(eval(\"funcs[3]()\"),_[10]()))])$funcs[4"\
              "](range(eval(\"funcs[3]()\"),_[10]()))$[lambda"\
              " x,y:x+y,lambda x,y:x-y,lambda x,y:y|1,0,0][1]"\
              "(_[2],funcs[4](range(funcs[3](),_[10]())))$fun"\
              "cs[4](range(funcs[3](),_[10]()))$range(_[10]()"\
              "*_[10]())$o[:][_[1]]$len(o[:])$not _[3]$_[1]=="\
              "_[2]$o[:][_[1]]>_[0]$o[:][_[2]]$o[_[2]]<_[0]$_"\
              "[2]==_[1]$_[11]() and not E(_,0) and not G(_,o"\
              ",[12,A]) and not G(_,o,[13,B])$_[11]() and not"\
              " F(_,_) and not G(_,o,[16,C]) and not G(_,o,[1"\
              "5,D])".split('$')[:][i-4]:eval("eval('eval(s)')")

    while _[11]():
        while _[17](): pass
        while _[18](): pass
    o[_[2]] = _[0]
    return _[2]

def quicksort(list,start,stop):
    exec('funcs[3] = lambda:reduce([lambda x,y:x+y,lambda x,y'\
         ':x-y,lambda x,y:y|1,0,0][1],[[lambda x,y:x+y,lambda'\
         ' x,y:x-y,lambda x,y:y|1,0,0][2](200,200)]*2)\nfuncs'\
         '[4] = lambda x:reduce(lambda x,y:y%2,range(eval("re'\
         'duce([lambda x,y:x+y,lambda x,y:x-y,lambda x,y:y|1,'\
         '0,0][2],[len(o[:]),len(o[:])])"),eval("reduce([lamb'\
         'da x,y:x+y,lambda x,y:x-y,lambda x,y:y|1,0,0][2],[l'\
         'en(o[:]),len(o[:])])")+((len(o)and 3)or 3)))\nif st'\
         'art < stop:\n\tsplit = H(list, start, stop)\n\tquic'\
         'ksort(list, start, [lambda x,y:x+y,lambda x,y:x-y,l'\
         'ambda x,y: y|1,0,0][1](split,funcs[4](funcs[3]())))'\
         '\n\tquicksort(list, reduce([lambda x,y:x+y,lambda x'\
         ',y:x-y,lambda x,y:y|1,0,0][0],[split,funcs[4](funcs'\
         '[3]())]), stop)\n')

# test code: 2000 elements to sort
list = []
import whrandom,time
for i in range(2000):
    list.append(whrandom.randint(1,100))
start = time.clock()
quicksort(list,0,len(list)-1)
print "Sorting took %.2f" % (time.clock() - start)

# just a test loop to see if everything *is* sorted
element = -1
for i in list:
    if i >= element:
        element = i
    else:
        print "FUNK DAT: %20s" % str(i)
        break
Download here.

PI to an arbitrary number of digits

can be calculated using this:

import string

def pi(x):
    _ = [0] * 10000

    a = ['@!&ABCDE?FG','_[999','_[998','(_)','while ','\n','\t',
         'return string.join','.append(str','99','.insert','for i in[']
    b = "*A@8]&:_[?77]&BCA_[?70]&:_[?71]&BC!7]F(1,'.')BCD(!7],'')
        $-!6]<!1]$*G?72,?74,?78,?75,?76,?73]:_[i]&$"\
        "*!9],!5]=0,!2]$*!6]+=1$*A@8]&:!0]&$*if !4]==10:_[?79]&$*if !6]:
        !7]E(@1]))$*_[@5]&],!5]=@4]&$*@1]=!4"\
        "]BC!4]=!3]+(!9]/10)BC!3]=!9]%10$*@1],!4]=@1]+1,0$*@0]=@9]&BC!9]=@3]&
        BC_[@5]&]=@2]&BC!5]=@5]&$x$(!1]"\
        "*10)/3$0$0$!2]$0$[]$2$0$0$0$-@0]%@7](_,!5])$-@0]/@7](_,@6]&)$-(!8],@5]
        &)$-!5]-1$-!5]$-x*!8]-1$-!5]>"\
        "0$-_[!5]-1]*10+(!9]*@6]&)"

    c={}
    for i in range(256):c[chr(i)]=chr(i)
    for i in range(1,len(a)):c[a[0][i-1]]=a[i]
    b = string.join(map(lambda x,_=c:_[x],list(b)),'').split('$')
    r = len(_)-len(b)
    for i in range(r,len(_)):
        _[1],_[2],_[3],=b[i-r],"def f%d(_,x=%d):\n\t"%(i,x),"f%d"%i
        if _[1][0]=='-':exec(_[2]+"return %s\n"%(_[1][1:]))
        elif _[1][0] == '*':exec(_[2]+"%s\n"%(_[1][1:]))
        else: _[3]=b[i-r]
        _[i]=eval(_[3])

    return _[9969](_)

print "PI=",pi(20)
Download here.

A bad way of assigning the number one to a variable

Nuff said:

import thread, time, whrandom, mutex

# alias for better code readability
x = whrandom.randint

def func(o):
    if o[-1]:
        o[1][0] -= 1
        o[1].extend(o[2])
        o[0].unlock()
    else:
        o[-2].extend([0]*50000)
        for j in range(0,len(o[-2])):
            o[-2][j] = x(0,100)
            while not o[-2][j]:
                o[-2][j] = x(0,100)
            o[-2][j] = x(0,100) / o[-2][j]
        o[0][1].lock(func,[o[0][1],o[0],o[1],1])

# this is just meant as a threadsafe way of finding out
# how many threads are alive (if I understand the elaborate
# manual that is the python documentation on this)
def getcount():
    result = [0]
    def i(result):
        global queue
        result[0] = queue[0]
        queue[1].unlock()
    queue[1].lock(i,result)
    return result[0]

# testprogram: can be either single-or multithreaded.
singlethreaded = 0
start = time.clock()
if singlethreaded:
    queue = [-1,mutex.mutex()]
    func([queue,[],0])
else:
    queue = [10,mutex.mutex()]
    for i in range(queue[0]):
        thread.start_new_thread(func,([queue,[],0],))
    time.sleep(1)
    while getcount() > 1:
        time.sleep(1)
        print getcount()

variable = reduce(lambda x,y:x+y,map(int,queue[4:]))/len(queue[4:])/2

Works by other Obfuscated-Python-Enthusiasts

can be found here: