The idea of this ridiculous program is a long obsession of mine - to author a low-level programming language in which every possible text input would constitute a valid program, and then produce some interesting or bizarre results - then provide a code builder that could be used to hide algorithms in bad poems.
Hiding plain covert messages in text and images is old and busted - but fairly sophisticated algorithms are undeniably the new hotness. So, write a sappy love letter and illegally export crypto or propagate DeCSS all at once! Heck, write a short poem to execute "Hello world", a longer one to play Sokoban, and then find secret satanic messages in your favourite piece of existing prose. Right. The name of this program itself is a joke on the work of William McGonagall - and I'm not kidding, a piece of awful, steganographic "Hello world" prose could go this way:
Now, having coded the language interpreter as such, I thought it would be also nifty to make it possible to employ a simple cryptographic transformation that could be used to hide messages from random observers, and reveal them to authorized parties only - and so, an optional passphrase may be supplied to provide a bit of toy crypto on top of it. So, without further ado:
Or, perhaps you'd rather write meaningful algorithmic poetry, you intellectual property thief? All right, the deal is pretty simple:
The underlying programming language uses 16 linearly arranged cells of 6-bit memory using unsigned integer arithmetic with no range checking. The memory is accessed by hovering two 3-bit pointers, a read and write head, over the range. These pointers may be moved in both directions with RDL, RDR, WRL, and WRR opcodes respectively. SWAP switches read and write head pointers. Memory cell under the write head may be modified by zeroing it (ZERO), adding an immediate 6-bit value (ADD), or adding a value read from underneath the read pointer (ADD_M).
Program control flow is achieved through the use of 8 location registers that may be set to a current code location with LABEL opcode. These registers are initially populated with first occurences of these opcodes during the compilation stage, and may be then changed dynamically. An unconditional jump to a label is achieved with JUMP opcode; JE jumps if cell value under read head is equal to the one under write head, and JA jumps is the former is greater than the latter. If a runtime option is checked, jump directives will expire after firing 64 times (which is useful for examining the behavior of random text, where endless loops may occur).
Console I/O uses a custom 6-bit alphabet (see here). READ opcode prompts for user input (waiting the number of seconds specified under read head divided by 10, 0 for indefinite), and stores read value at current write head offset (user may choose to hit ESC, in which case, no write will occur, and all future READ opcodes will be silently ignored). WRITE opcode writes an immediate integer (and WRITE_M copies data from underneath the read pointer) to screen. Screen is arranged as a 2D array of 32 by 16 characters, with automatic cursor advance, and output coordinates controlled by SETX and SETY opcodes. SETCOL sets output color for subsequent text to one of 8 predefined colors (gray, red, green, blue, cyan, purple, yellow, or white).
Input file processing: each non-zero run of letters constitutes a single command. Any run under 4 characters is mapped to a no-op instruction. All runs 4 characters and more are mapped to opcodes by calculating a simple 8-bit checksum of every run of letters (and in passworded mode, by throwing in an output from a crypto-safe PRNG seeded with the password), modulo the number of opcodes available (254).
It might sound like a Turing tarpit, but is actually fairly usable with the provided builder.
Oh, complete compiler and builder source code: click here!
Copyright 2007 by Michal Zalewski <firstname.lastname@example.org>