An esoteric Python transformer that transforms your code into a cryptic dialect using only [(+travels)].
Why?
·
How It Works
·
Installation
·
Usage
PyfuckV2 is a mind-bending exploration of Python's dynamic nature. It takes any valid Python script and transmutes it into a highly unreadable but perfectly functional format, using an extremely limited set of characters: (, ), [, ], +, t, r, a, v, e, l, s.
This project serves as an educational deep dive into Python's introspection capabilities and a tribute to the esoteric programming concepts pioneered by JSFuck and the original PyFuck.
Disclaimer: This tool is for educational and recreational purposes only. It is a proof of concept, not a tool for serious security or obfuscation. The generated code is extremely slow, inefficient, and easily reversible. Do not use this in production environments.
The goal of PyfuckV2 is to answer the question: "What is the absolute minimum set of characters needed to represent any program in a Turing-complete language like Python?" It's a fun way to:
- Explore Metaprogramming: Understand how Python can build and execute code on the fly.
- Learn About Introspection: See how we can access the "guts" of Python's built-in types and functions to construct new functionality from scratch.
- Create a Programming Puzzle: The output is a fascinating, if horrifying, piece of code that challenges our understanding of syntax.
Take a simple Python script...
# hello.py
print("Hello, World!")...run it through PyfuckV2...
pyfuck -i hello.py...and witness the transformation.
# obfuscated.py (output is heavily truncated for readability)
eval(str(eval)[eval(str(+all([]))+str(all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])))]+eval(str(str)[+all([])]+str(eval(str(str)[all([])+all([])+all([])+all([])]+str(str)[all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])]+str(str)[eval(str(+all([]))+str(+all([[]])))]+str(eval(str(eval)[eval(str(+all([]))+str(+all([[]])))]+str(str)[all([])+all([])]+str(eval)[eval(str(+all([]))+str(all([])+all([])+all([])+all([])+all([])+all([])))]+str(str)[all([])+all([])+all([])]+str(str)[all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])]+str(())[+all([[]])]+str(+all([]))+str(())[+all([])]))[+all([])]+str(str)[+all([])]+str(eval)[eval(str(+all([]))+str(all([])+all([])+all([])+all([])+all([])+all([])))]+str(eval)[all([])+all([])]+str(eval)[eval(str(+all([]))+str(all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])+all([])...Despite its appearance, this is valid Python code that executes perfectly and prints "Hello, World!".
- Minimal Character Set: Uses only
[(+travels)]to represent any Python script. - Zero Imports: The generated code is completely self-contained.
- Powerful CLI: A simple and intuitive command-line interface for all your obfuscation needs.
- Multiple Modes:
exec: (Default) Generates code that executes the input script.eval: Generates an expression that evaluates to the input script's result.string: Generates an expression that evaluates to the input script as a string.
The magic behind PyfuckV2 is a "bootstrapping" process that constructs a usable character set from almost nothing. It's a chain of logical steps, each building upon the last.
-
Boolean Arithmetic (Getting 0 and 1): The process starts by generating integers. Python's boolean logic is the key:
all([])evaluates toTrue.+all([])coercesTrueto the integer1.all([[]])evaluates toFalse.+all([[]])coercesFalseto the integer0. Larger numbers are then created by summing1s.
-
Initial Characters (Scavenging from
str()): With numbers, we can index strings. By callingstr()on built-in objects likeevalandstr, we can "scrape" our first characters. For example:str(str)gives"<class 'str'>"str(eval)gives"<built-in function eval>"- Indexing these strings (e.g.,
str(str)[1]) gives us'c','l','a','s', etc.
-
Unlocking
chr()(The Rosetta Stone): The crucial breakthrough is to construct the string'chr'using the scavenged characters and then calleval('chr'). Once thechrfunction is accessible, PyfuckV2 can generate any character from its ASCII/Unicode ordinal value. This is the "Rosetta Stone" that unlocks the entire character set. -
Unlocking
exec()(Executing Scripts): Similarly, once the character'x'is available (viachr()), the script constructs and evaluates the string'exec'. This allows the execution of multi-line scripts and statements that don't return a value (likeimportorprint). -
Final Assembly: With the power of
chr()andexec(), the original Python script is assembled character by character into a very long string. This string is then wrapped in a finalexec()oreval()call to be executed by the Python interpreter.
You can install PyfuckV2 directly from this GitHub repository using pip.
pip install git+https://github.com/SSL-ACTX/pyfuckv2.gitPyfuckV2 is designed to be used as a command-line tool.
usage: pyfuck [-h] [-i FILE] [-o FILE] [-m {string,eval,exec}] [-v] [source]
A Python obfuscator using only **[(+travels)]** characters.
positional arguments:
source The Python code string to encode. If not provided, reads from stdin.
I/O Options:
-i FILE, --input FILE
File to read Python code from. Overrides the positional source argument.
-o FILE, --output FILE
File to write the encoded output to. Prints to stdout by default.
Encoding Options:
-m {string,eval,exec}, --mode {string,eval,exec}
Encoding mode:
string: creates an expression evaluating to the source string.
eval: creates an expression that evaluates the source code.
exec: creates an expression that executes the source code (default).
-v, --verbose Show verbose output during the character bootstrapping phase.
| Description | Command |
|---|---|
| Encode a string directly | pyfuck 'print("Hello from the CLI!")' |
| Encode a file and save the output | pyfuck -i my_script.py -o obfuscated.py |
Encode from stdin using a pipe |
echo "import sys; print(sys.version)" | pyfuck |
| Generate a string expression | pyfuck -m string "42" |
| Use verbose mode to see the magic | pyfuck -v "1+1" |
Using the --verbose or -v flag provides a fascinating look into the bootstrapping process, showing how each character and function is "learned" before the final code is assembled.
$ pyfuck -v '42'[Verbose] Learned '<' -> str(str)[+all([[]])]...
⠋ Encoding...
[Verbose] Learned 'c' -> str(str)[+all([])]...
[Verbose] Learned 'l' -> str(str)[all([])+all([])]...
[Verbose] Learned 'a' -> str(str)[all([])+all([])+all([])]...
[Verbose] Learned 's' -> str(str)[all([])+all([])+all([])+all([])]...
[Verbose] Learned ' ' -> str(str)[all([])+all([])+all([])+all([])+all([])+all([])]...
This project was developed by SSL-ACTX and stands on the shoulders of giants in the esoteric programming world.
- JSFuck: The original and most famous implementation of this concept in JavaScript, which demonstrated that any JS code could be written with only six characters:
[]()!+. - PyFuck: An earlier Python implementation that served as a direct inspiration for this more feature-rich and robust version.
PyfuckV2 aims to modernize the concept with a clean codebase, a powerful CLI, and a more detailed explanation of its inner workings.
This project is licensed under the MIT License. See the LICENSE file for the full text.