Obfuscated Python

Not easy, but clearly possible. Click on this page's title to see where this page is referenced from - there you may find some examples or discussion.

I disagree with "not easy". While Python lends itself better than many other languages to writing clear code, there's nothing magical about the language that makes it hard to write code in the style of the InternationalObfuscatedCeeCodeContest. What part of Python doesn't lend itself well to obfuscation? I assume you're going to say syntactically-significant indentation, but that's not much of a deterrent.

In fact, there are some language features that make obfuscation fun:

  1. Tab and space are both allowable in indentation whitespace, which means you can make blocks that look inverted.
  2. You can rebind methods, alter base classes, and overload pretty much anything in the language
  3. Combine nested scopes with lambdas to produce truly evil side effects
  4. If you're clever, you can write most of your code as a series of nested list comprehensions (making the second word of that phrase a lie)


Sure! you have the great while..else for..else and try..else constructs! make fun with a for..else with continue or break or "raise StopIteration" and let the user guess where the control flow will appear.

Also use `foo`, and overload __nonzero__. And name "self" with another name or pass it here and there.

The fact that tab and space are both allowed only lets you make inverted-looking blocks if you can guarantee that the tab size isn't 8 for whoever's looking.

There are a number of ways in which Python's harder than C to make obscure in IOCCC fashion.

There's no preprocessor.
Python is strongly (but not statically) typed, so you can't play type-punning games.
Function definitions are more clearly marked, via the def keyword.
Statements and expressions are distinct, so that you can't put so much into the condition part of an if or a while.
There's no C-like for statement.

That's not to say obfuscated Python is impossible. You can be obscure in any language at all, obviously. But Python offers much less scope for syntactic obfuscation, and in C syntactic obfuscation provides rather a lot of the fun.
Anyone want to try their hand at some obfuscated Python? The backlinks are a good start...

Some other thoughts:
 - lambda(x,y):... is different from lambda x,y:
 - Use nested lists [a][b][c][d][e:f]
 - Type tricks can be done... int,str=str,int isn't exactly subtle, though
 - It's probably more stylish not to obfuscate using execs/evals and lambdas
 - Use a string as both code (via eval/exec) and data
 - Take advantage of readers' knowledge of other languages:
 print n, c, n**c

 - nested lambdas
 - redefine functions by assignment
 - make an single instance of the % operator used for both modulus and string formatting
 - same with +, * for addition, string concatenation, etc.
 - evade indentation enforcement by writing things in recursive pseudo-functional ways
 - do something like foo(bar(), baz()) where bar() redefines foo() and baz()
 - litter the code with numeric and string literals that look like they're doing something (but don't)
 - cause exceptions solely for the purpose of later extracting obscure data from them

I don't know if this is exactly related since it's not intentionally obfuscated, but I've got a polyglot (in this case, legal C/C++, perl and Python, see also HelloPolyGlots) quine (see QuineProgram) that has some pretty unreadable Python in it. http://www.phong.org/bf/polyglotC++PerlPythonC.c

Very nice (for some interpretation of the term ;-)
 # Here's an accumulator for 2.2 that has roughly a 1:6 evil:character ratio
 # It's not nearly at Perl or C levels, of course...
 class O(float):O,__new__=0,lambda O,_:O.__setattr__(O,"O",_+O.O)or O.O

See <http://www.python.org/cgi-bin/moinmoin/JustAnotherPythoneer> for various degrees of obfuscation of a simple task.

 [#[#[#[#[#[#[#[#[# By TaroOgawa #]#]#]#]#]#]#]#]#]

globals() .update({ "______": lambda x: globals() .update(( dict([[x] *2])))}), ______((( "Just"))) ,______(( "another" )),______ ("Python" ),______( "Hacker") ];print ( " ".join( [(Just),( (another) ),(Python ),Hacker] ));______

Cute, but it doesn't actually, you know, run or anything. It does under Python 2.3+ [Hint: Make sure you copy EVERYTHING including the credit line]

Functional programming is your friend!

Here's a fully-functional, English-aware version of "99 bottles" in Python. Enjoy. Additional bonus -- it fits on one line and doesn't use any cheap indentation or variable naming tricks.

  print ''.join('%(pre)s%(num)s %(bot)s on the wall, %(nul)s %(bot)s,\n%(tak)s\n' % (lambda c,b:
  {'pre':['','%s %s on the wall.\n\n' % (c,b)][abs(cmp(c,'Ninety-nine'))],
 'num':c, 'nul':c.lower(), 'bot':b,
 'tak':['Go to the store and buy some more... Ninety-nine %s.' % b,'Take one down, pass it around,'][abs(cmp(x,0))]
  })((lambda x,o: [(['Twenty','Thirty','Forty','Fifty',
  'Sixty','Seventy','Eighty','Ninety'][x/10-2]+'-'+o.lower()).replace('-no more',''), o][int(x<20)])(x, ['No more','One','Two',
  'Fifteen','Sixteen','Seventeen','Eighteen','Nineteen'][[x,x%10][int(x>=20)]]),'bottle%s of beer' % ['','s'][abs(cmp(x,1))])
  for x in xrange(99,-1,-1))

-- IvanTkatchev

That would have been so much shorter if Python had CommonLisp's FORMAT function... How so?

CommonLisp's FORMAT has number-to-word conversion built in, but only for English.

Put code in docstrings and execute the file again minus the first line, reversing the blockquotes. Example:

  print "This is the hidden code."
  print "This is the normal code."
  import sys
  codeToExecute = ''
  print "More hidden code."

Or simply

  def p(n):
    """print 'hidden code'"""
    return n**2
  exec(p.__doc__) # hidden code

Overwrite Fields

from __future__ import print_function; ''' print(q[1]('t9(}zw|q}/>VzrP}/q|zaJ Q>V')),exit(0)#''' q=lambda x,_=('c9*6iv"&s1[Y/`Oh7_|pEW:=!uT4+zeNl;Im\'X\\<-wabDMZ8ykgR@{r>B)~qKFdC3H0Q%,S}xVG](?^2#oPjJL.A$U fnt5'): type('').__dict__['}VJ|(@J}>'. translate(('_'*32+_+('__'*len(_))[:(1<<2)-1-(1<<8-2)]))](x,('_'*32+_+('__'* len(_))[:(1<<2)-1-(1<<8-2)]));globals()[q('11$C3qV}11')] = lambda _,q=q,__builtins__=__builtins__: __builtins__.__dict__[q('11$C3qV}11')](q(_));q2=( lambda globals=(lambda q=(lambda x: getattr(__import__('q('),x)): q): (lambda os, __import__=q: (globals()(__import__(os)))))(); q=[q2('q3>|')(__import__( '(P(').__dict__[q('JVR%')][0],0),q];q2('^93o')(3,0);raw_input();input()

Someone replaced the content of this page with a code listing. I have reverted the change, as the new content was vastly less helpful than what used to be here aside from as an overly verbose SelfDemonstratingArticle?.


View edit of November 20, 2014 or FindPage with title or text search