# Obfuscating TeX

Given TeX's system of catcodes, I imagine that one can obfuscate TeX to a remarkable degree. With a view to learning more about the internals of TeX, I ask: How might I go about adding a block of obfuscated code to my document? Let's say I want to add a watermark to my document that I don't want my co-author to be able to edit. How might I do that?

What tricks can I use to make a certain piece of code harder to understand?

-
See also Can I see a plain TeX source file whose answers quickly morphed into obfuscation. –  Alan Munn Jun 17 '11 at 18:23
–  Yiannis Lazarides Jun 17 '11 at 19:01
“There is an annual obfuscated C programming contest. The same would be rather pointless for TeX: every nontrivial task has only obfuscated solutions, anyway.” – tug.org/interviews/kastrup.html –  Philipp Jun 18 '11 at 6:39
are you using XeTeX? It allows a much larger range of characters, and that might be used to store several Latin characters per character. –  Bruno Le Floch Jun 18 '11 at 13:24
And what happens if your co-author just remove the lines of obfuscated code? –  El Andi Sep 22 '13 at 22:22
show 1 more comment

Try out xii.tex. It's a plainTeX file, you can find it on CTAN.

And Enrico “egreg” Gregorio produced a similar code, even shorter. See in What is the most bizarre thing you have seen done with TeX, where it is called xcix.tex.

-
Wow, that is pretty impressive. In comparison, obfuscated C reads like a newspaper :-) –  Daniel Jun 17 '11 at 18:26
There's also Brainfuck which is obfuscated almost by design. –  Alan Munn Jun 17 '11 at 18:37
@doncherry: If you look at the answers to the question Yiannis has linked to (comment on the question) then you will see how to analyse xii.tex. It is most enlightening: \tracingall is your friend here :-) –  Joseph Wright Jun 17 '11 at 20:14
@Alan: I don't find Brainfuck all that hard to read, I have to say. You shift cells left and right, increment or decrement their contents, and input/output their contents as characters - only the looping construct holds any slight mystery. Tedious, verbose, encoding intense, but not really hard to figure out. Tex is much more interesting. I haven't see obfuscated Tex that really got to grips with the joys of \let\\\loop\let\|\ifx\let\/\repeat, say. –  Charles Stewart Jun 18 '11 at 8:35
Let's reimplement TeX in brainfuck! –  Seamus Jun 23 '11 at 11:01

If you are using XeTeX, here is some (slightly obfuscated) code to pack (\p) pairs of Ascii characters into one Unicode character, storing the result in \toks0 (token register, which I called \| below), or unpack (\u) the result.

The encoding uses the fact that visible ascii characters have a character code (acessed with \number) between 32 (space) and 127 (tilde), so they can be stored in two digits by shifting by 32. Four digits are then packed in one character by adding 10000 (minus the two shifts of 32, hence 6768, minus a 32 hidden in the definition of \., hence 6736), to ensure that this gives 5 digits (starting with 1).

Decoding reads characters one at a time, through \number, which gives 1, followed by two pairs of digits. We add 32 to each pair, set the uppercase code of . to that value, and store \uppercase{.} in \|.

Stopping the loop is done by inserting \iffalse at the right place in both packing and unpacking.

% Packing 2 ascii char per Unicode char with XeTeX.
\begingroup
\toksdef\|0
\let\ea\expandafter
\def\>{\uppercase{\|\ea{\the\|.}}}
\def\.{\uccode.\numexpr32+}
\def\p#1{\|{}\ea\q#1\ {\ \iffalse}\ \fi\relax}
\def\q#1#2{\.\number#100+#2+6736\>\q}
\def\u#1{\|{}\ea\v\number#1 \^^J{\iffalse}..\fi\relax}
\def\v1#1#2#3#4{\.#1#2\>\.#3#4\>\ea\v\number}
% Example
\p{The\ main\ author\ is\ Seamus!}\showthe\|
\ea\u\ea{\the\|}\showthe\|
\endgroup
\csname @@end\endcsname\end


The group is there to avoid leaking out the definitions. Of course, you probably want to only leave the definitions for \u, and write \u{㮨䈄䃉䠨䘾❙䝼㭁䃁䢗❴}\message{\the\|} in your document.

-

I have just found \char and so:

\documentclass{article}
\begin{document}
\char'110 \char'105 \char'114 \char'114 \char'117 \kern .8em \char'127 \char'117\char'122 \char'114 \char'104
\end{document}


Also, I wonder if there's a way to access what your document looks like after it's all been expanded down to primitives. I think that would in itself be pretty obfuscated...

-
As gets pointed out a lot, TeX does not expand to primitives independent of typesetting. The nearest you can get is \tracingall`. –  Joseph Wright Jun 30 '11 at 17:30
@Joseph well, what I meant was, I wonder if there's a way to see what the output would look like if you expanded a whole bunch of the macros (but perhaps not all of them)... –  Seamus Jul 1 '11 at 10:19