Skip to main content

scramblenames

Obfuscate Python source code by scrambling variable, function, and class names into meaningless eight-character identifiers, while keeping the program working exactly the same. Comments and docstrings are removed by default too. The point is to strip every human-readable clue from a program without changing what it does.

It does not un-scramble — this is a one-way transform.

Install

pip install scramblenames

scramblenames uses libcst to preserve formatting (and comments/docstrings when you choose to keep them).

Library usage

from scramblenames import scramble

source = '''
def add(a, b):
    total = a + b
    return total
'''

print(scramble(source, seed=1))
def gFb51yBM(iK2ZWeqh, FWCEPyYn):
    WXaSCrUZ = iK2ZWeqh + FWCEPyYn
    return WXaSCrUZ

scramble() accepts the code as a string, a pathlib.Path, or a string filename of an existing file:

from pathlib import Path
scramble(Path("mymodule.py"))     # read from a Path
scramble("mymodule.py")           # read from a filename
scramble("x = 1\n")               # scramble a code string directly

Scrambling a whole directory

scramble_tree() scrambles every matching file under a directory, mirroring the tree into a destination directory:

from scramblenames import scramble_tree

scramble_tree("myproject/", "obfuscated/", import_safe=True)

Each file is scrambled independently, so use import_safe=True for multi-file packages — otherwise a public name renamed in one module wouldn't be matched at its import site in another. Use include/exclude globs and recursive=False to control which files are processed.

Errors

Source that can't be parsed raises scramblenames.ScrambleError, carrying the filename, line, and column of the problem when available.

Options

scramble(
    source,
    import_safe=False,       # keep top-level function/class/global names
    strip_comments=True,     # remove all comments
    strip_docstrings=True,   # remove module/function/class docstrings
    style="random",          # "random" | "hex" | "reorder"
    seed=None,               # int for reproducible output
)
Option Effect
import_safe=True Assume the file may be imported by other code. Module-level function, class, and global names are kept; only function-local names are scrambled.
import_safe=False (default) Also scramble module-level function, class, and global names (except those in __all__). Best for standalone scripts.
strip_comments=True (default) Remove every comment. A first-line shebang (#!...) and a PEP 263 encoding cookie are always kept. Set False to keep all comments.
strip_docstrings=True (default) Remove the leading docstring of the module and of every function and class (an empty body becomes pass). Set False to keep them.
style="random" Eight random alphanumeric characters, first is always a letter.
style="hex" Eight hexadecimal characters, first is always a letter (a–f).
style="reorder" A permutation of the original name's own characters.

Command line

scramblenames mymodule.py                       # scramble to stdout (strips prose)
scramblenames mymodule.py -o out.py             # write to a file
scramblenames mymodule.py --import-safe         # keep the public API
scramblenames mymodule.py --keep-prose          # keep comments + docstrings
scramblenames mymodule.py --style hex --seed 7  # reproducible hex names
cat mymodule.py | scramblenames                 # read from stdin

# scramble a whole project into a mirrored output directory
scramblenames myproject/ -d obfuscated/ --import-safe
scramblenames src/ -d out/ --exclude '*_test.py' --no-recursive

Scrambling a directory (or more than one file) requires -d/--output-dir, which mirrors the input tree. The paths written are listed on stderr. A parse error prints a clean message and exits non-zero.

What is and isn't scrambled

Every generated name is a valid Python identifier and never a keyword, so the output is always syntactically valid and behaves identically to the input.

Scrambled

  • Local variables inside functions.
  • for, with ... as, except ... as, and walrus targets.
  • Comprehension and generator variables.
  • Module-level functions, classes, and globals — only when import_safe=False.
  • Nested function and class names (they are local to their enclosing function).
  • Parameters that can't be reached by keyword — positional-only params, *args, and **kwargs — always.
  • Other parameters, when the function is safe to analyze: it's local (its own name is scrambled too), undecorated, never passed around or stored, and never called with ** unpacking. Every keyword argument at its call sites is rewritten to match (f(name=1) → f(x7Kd2p9q=1)).

Never scrambled (renaming these could break the program)

  • Attributes — x.foo, self.foo, and the string entries in __slots__, since the object's type generally can't be proven.
  • Method names — reached by attribute access, like other attributes.
  • Method and public-API parameters — outside callers may pass them by keyword, so keyword-eligible parameters of methods, of the public API, and of functions that escape the module are kept.
  • Imported names and builtins.
  • Names listed in __all__, and dunder names like __init__.

Because attributes are preserved and parameters are only renamed when all call sites are visible, code that relies on dynamic access — getattr/setattr with computed strings, locals(), **kwargs forwarding by string key — keeps working.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[test]"
pytest

License

MIT

Metadata

Release files for scramblenames 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scramblenames 0.1.0
File Size Uploaded Provenance Actions
scramblenames-0.1.0.tar.gz 24.0 kB Without provenance Details for scramblenames-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for scramblenames 0.1.0
File Interpreter ABI Platform Actions
scramblenames-0.1.0-py3-none-any.whl Python 3 none any Details for scramblenames-0.1.0-py3-none-any.whl

Total release size: 41.3 kB

Release files / scramblenames-0.1.0.tar.gz

Download URL scramblenames-0.1.0.tar.gz
Size 24.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6b3e66dc98ecfd9f13af846b4e6908c6f813c0a6474d05c0f93315cbcb435ded
BLAKE2b-256 checksum
How to use checksums
cecd8f7fa06204762fa3e5747a3346d6ede6a4b564ed69e7b94e19c4fae62c5d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.8

Release files / scramblenames-0.1.0-py3-none-any.whl

Download URL scramblenames-0.1.0-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
42645dbc3f618bfd808b9545a760b1c8ead9200f3e15d7f44867e725e5d9b3ee
BLAKE2b-256 checksum
How to use checksums
2deaaf6b87face20ee9340b67a0d42a326f4d6c85fd653bad9f452b046dedd4f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.8

Security for scramblenames 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page