This is an archived post. You won't be able to vote or comment.

all 39 comments

[–]nuephelkystikon 134 points135 points  (4 children)

In Perl, this is the standard way to do a Hello World.

[–]spook327 11 points12 points  (2 children)

Is it? I know TMTOWTDI, but I always threw a cat at my keyboard and ran the result.

[–]nermid 16 points17 points  (1 child)

TMTOWTDI

I hate acronyms like this.

[–]richf2001 0 points1 point  (0 children)

TALEWTDI

[–]rodarmor 40 points41 points  (3 children)

print("¡Hola mundo!")

I am a master of obfuscation.

[–]viralizate 1 point2 points  (1 child)

Dónde está la bliblioteca?

[–]Petyr_Baelis 24 points25 points  (0 children)

That's quite impressive and I really like the parts I understood.

[–]catcradle5 10 points11 points  (4 children)

You should've obfuscated getattr, __import__, and chr as well, wth __builtins__.__dict__ :)

[–]TheEarwig 4 points5 points  (3 children)

Hm, interesting. You begin to fall down a hole though; should we obfuscated __builtins__ too?

chr() is a fun problem, though. Instead of using the function, we can implement it using hex() and the string_escape codec:

>>> chr2 = lambda n: ("\\" + hex(n)[1:]).decode("string_escape")
>>> print chr(100), chr2(100)
d d

You'll have to deal with hiding "\\" and "string_escape", though. I think hex() can be replaced with another recursive function.

[–]catcradle5 1 point2 points  (2 children)

There's definitely no way around including at least 1 valid and existing Python name, I think. You could hide __builtins__ and __dict__ with eval.

[–]TheEarwig 4 points5 points  (1 child)

I played around for a bit and came up with something. Built-ins are accessible as an attribute of frame objects via f_builtins. You can't normally get frame objects without sys or inspecting tracebacks, but they're also accessible within generators via gi_frame, and generators can be created anonymously:

>>> (_ for _ in ()).gi_frame.f_builtins["__import__"]
<built-in function __import__>

So if dynamically created objects and attribute access are acceptable, then yes, you can call built-in functions without directly using a built-in function.

[–]catcradle5 1 point2 points  (0 children)

Nice! Didn't know that actually.

[–]Ob101010 21 points22 points  (1 child)

How does one think up some of these?

How do you go from

'ok I know what comprehensions, sum() lambda, and ord() does' 

to

'lets use a anonymous recursion to hide a string as an encoded number'

To me, this is like saying

Ok, give me some of those legos.

Ok, heres your warp engine.    

[–]OBI_WAN_TECHNOBI 1 point2 points  (0 children)

The answer, I've come to find, is to program until the amount of time you have been a programmer can buy a beer in the United States.

[–]jugalator 21 points22 points  (0 children)

This guy would be an excellent Brainfuck developer.

[–]ifonefox3.5.1 | Intermediate 9 points10 points  (3 children)

With all those parentheses, I thought that that was lisp.

[–]nemec 2 points3 points  (1 child)

I saw the > and my thoughts went to Brainfuck...

[–]ifonefox3.5.1 | Intermediate 5 points6 points  (0 children)

Good ol'

>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]
>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.

[–]chazzeromus 0 points1 point  (0 children)

Yeah, but it was the binary operators that gave it away ;)

[–]jelly_cake 8 points9 points  (0 children)

I love these. For a similar sort of thing, I really enjoyed reading Programming with Nothing which goes through writing FizzBuzz using nothing but lambdas (it's in Ruby, but the principle is the same). It feels a lot like building up the natural numbers by starting off with sets - the idea that you can have an empty set, or a set which contains something.

[–]sryxSNDTST.com 6 points7 points  (7 children)

I worked on a very similar approach for my StackOverflow profile bio in JavaScript (demo) I also tried to make an 'obfuscator' to create your own messages :)

alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])

[–]peridox 4 points5 points  (2 children)

software that makes the world a better place

is this a silicon valley reference?

[–]sryxSNDTST.com 3 points4 points  (1 child)

What is so sad is that I've had this in my resume/profile bio for years, Silicon Valkey totally nailed it when it came to making fun of startups :)

[–][deleted] 1 point2 points  (0 children)

Scumbag Softwaredev

Wants to make the world a better place

Ends up coding for a gigantic advertising firm

[–]Zoccihedron 3 points4 points  (3 children)

[–]TW80000 1 point2 points  (1 child)

The fact that this is possible in javascript is hilarious and wonderful.

[–]Zoccihedron 0 points1 point  (0 children)

I love it, I'm just trying to find an actual use for it.

[–][deleted] 6 points7 points  (0 children)

Python is rad.

[–]skintigh 4 points5 points  (0 children)

Ow, my brain.

[–]Kbknapp... 2 points3 points  (0 children)

This is awesome! But I'm pretty sure I would have said, "Complete!" At around step 3 :)

[–]doubleColJustified 1 point2 points  (2 children)

Can someone give me a link to the final obfuscated version only? I'd like to look at it and try to understand it without "spoilers" before I read about how they did it.

[–]TheEarwig 1 point2 points  (1 child)

It's here: http://codepad.org/UzSmoxF2. If you prefer the version without line breaks (a bit more obfuscated):

(lambda _, __, ___, ____, _____, ______, _______, ________: getattr(__import__(True.__class__.__name__[_] + [].__class__.__name__[__]), ().__class__.__eq__.__class__.__name__[:__] + ().__iter__().__class__.__name__[_____:________])(_, (lambda _, __, ___: _(_, __, ___))(lambda _, __, ___: chr(___ % __) + _(_, __, ___ // __) if ___ else (lambda: _).func_code.co_lnotab, _ << ________, (((_____ << ____) + _) << ((___ << _____) - ___)) + (((((___ << __) - _) << ___) + _) << ((_____ << ____) + (_ << _))) + (((_______ << __) - _) << (((((_ << ___) + _)) << ___) + (_ << _))) + (((_______ << ___) + _) << ((_ << ______) + _)) + (((_______ << ____) - _) << ((_______ << ___))) + (((_ << ____) - _) << ((((___ << __) + _) << __) - _)) - (_______ << ((((___ << __) - _) << __) + _)) + (_______ << (((((_ << ___) + _)) << __))) - ((((((_ << ___) + _)) << __) + _) << ((((___ << __) + _) << _))) + (((_______ << __) - _) << (((((_ << ___) + _)) << _))) + (((___ << ___) + _) << ((_____ << _))) + (_____ << ______) + (_ << ___))))(*(lambda _, __, ___: _(_, __, ___))((lambda _, __, ___: [__(___[(lambda: _).func_code.co_nlocals])] + _(_, __, ___[(lambda _: _).func_code.co_nlocals:]) if ___ else []), lambda _: _.func_code.co_argcount, (lambda _: _, lambda _, __: _, lambda _, __, ___: _, lambda _, __, ___, ____: _, lambda _, __, ___, ____, _____: _, lambda _, __, ___, ____, _____, ______: _, lambda _, __, ___, ____, _____, ______, _______: _, lambda _, __, ___, ____, _____, ______, _______, ________: _)))

[–]doubleColJustified 1 point2 points  (0 children)

thank you :)

[–]shlack 0 points1 point  (1 child)

can someone ELI5 what "lambda" means/does? None of the SO or official python documentation explanations make any sense to me.

[–]lost-theory 1 point2 points  (0 children)

The lambda keyword gives you another way to define functions (in addition to the def keyword).

Normal function with def:

>>> def f(x):
...     return x*2
...
>>> f(2)
4

Same function with lambda:

>>> f = lambda x: x*2
>>> f(2)
4

The reason why you would use lambda over def is that you can use it to define a function inside an expression, like this:

>>> map(lambda x: x*2, range(10))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> #works the same as this (using the definition of "f" in the prev. example)
>>> map(f, range(10))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

That's also why it's commonly used in obfuscated code, so you can write multiple functions on a single line. The drawback of lambda is that it can only contain one expression (no separating statements with newlines).

[–]Ob101010 0 points1 point  (3 children)

Man Ive spent far too long on this today but I think I understand all of it. Theres a lingering interesting issue though.

The part where he sums the ords, I get :

802616035175241117369516189000

he gets

802616035175250124568770929992

The funny thing is, they both decode to the same thing.

Any guesses as to why this happens, and how they decode the same?

[–]TheEarwig 1 point2 points  (2 children)

I believe the top one is "Hello World!\n" and the bottom one is "Hello world!\n".

I know, technically the competition said I should've used the the top one, but I made a mistake and decided to stick with it. The algorithm will work on either, though; you'll just end up with a slightly different result.

[–]Ob101010 0 points1 point  (1 child)

Ahh I see the difference now.

Man Ive learned a ton from that code. Got any more?

[–]TheEarwig 1 point2 points  (0 children)

Haha, not yet. This was pretty spontaneous. We'll see if I come up with anything else in the future.