Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/BenWiederhake/ohno
Interpreter for an esoteric, overly hard language
https://github.com/BenWiederhake/ohno
Last synced: 2 months ago
JSON representation
Interpreter for an esoteric, overly hard language
- Host: GitHub
- URL: https://github.com/BenWiederhake/ohno
- Owner: BenWiederhake
- License: gpl-3.0
- Created: 2016-03-31T16:21:42.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2023-01-08T15:48:12.000Z (about 2 years ago)
- Last Synced: 2024-11-14T12:22:53.333Z (2 months ago)
- Language: C
- Homepage:
- Size: 22.5 KB
- Stars: 16
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- AwesomeInterpreter - ohno
README
# ohno - Interpreter for "ohno"
"ohno" is an esoteric "programming language" designed to be cryptographically difficult.
"ohno" does not stand for "overly hard, nonsensical language"
## What.
"ohno" is a highly advanced language. For example, it uses the very
modern hashing algorithm Keccak to compile the input into ohno
bytecode. Thus, portability is guaranteed, as Keccak has been
implemented on lots of platforms so far. This way, even large programs
can be compiled very quickly.The generated bytecode is then interpreted essentially as Brainfuck
instructions, yet another example of the progressive, highly advanced
nature of ohno.Since it uses a secure hashing algorithm to generate the byteode,
disassembly of complex programs is as hard as preimage attacks on SHA3.The overly difficult nature of ohno makes sure that only the best
programmers with the most advanced hardware can hope to find an ohno
program that does something somewhat useful.Feel free to use the program `search` with `grep` to search for good
ohno programs. The `cat` example was found using these tools.## Seriously. What?!
Of course all of this isn't to be taken too seriously. Obviously ohno
isn't *truly* compiled, as it uses an interpreter. But it could be.
Shoot me a PR that compiles ohno into actual assembly, probably using
LLVM? :DOhno is intended to rival
[Malbolge](https://en.wikipedia.org/wiki/Malbolge) in difficulty, as
now the "hashing"
isn't some home-made algorithm that may or may not have nice
properties, but instead uses industry-grade hashing.## Spec for `.ohno` files
A valid `.ohno`-file needs to:
- Contain at least 4 bytes
- Start with 4 bytes, big endian, which is the amount of bytes of the bytecode.
- The rest is used to seed the hashing function.Thus, nearly all files are ohno programs; albeit they probably don't do
anything useful. Especially not if the first byte is not `0x00`.## ohno bytecode
The ohno bytecode is nibble-based, and technically not even that: only
the last three bits of each nibble are considered, and mapped to the
Brainfuck instructions (in order) `+-{}><,.`, while ignoring the
highest bit. Note that `{}` is similar to Brainfuck's `[]` but not identical.As Brainfuck is underspecified, here's the filled-in details:
- The tape is infinite in both directions and initialized to 0.
Well, as infinite as something can be on a finite machine.
- The tape can hold values from 0 to 255, inclusively, and will wrap.
(Unless you have an optimizing compiler that actually exploits the UB
on integer overflow. In that case, it doesn't wrap, but UB's.)
- Where `[xxx]` in Brainfuck is equivalent to `while (*tape_ptr) { xxx }` in C,
ohno's `{xxx}` behaves like `do { xxx } while (*tape_ptr);` in C.
Note that this
[probably is](http://cs.stackexchange.com/q/47603)
[still Turing-complete](http://cs.stackexchange.com/a/33711).
- Technically, the `}` only behaves as specified above if there is an
appropriate `{` to which it can jump. Otherwise, the program hangs
and never terminates.
- You can stack at least 4 billion (`2^32 - 1`) brackets.
- Stack depth at the end of the program is ignored. Notice that this
means that you don't really need to care about balanced brackets, as it
will either hang or terminate successfully, but never crash!
(Unless you're a weirdo and want to do something useful.)
- `,` (read) stores the current input *byte* on the tape. Good luck with
doing anything Unicode-related.
- If `,` (read) encounters the end of `stdin`, then the program terminates
with exit code 0.## `cat.ohno`
I believe there is only one somewhat meaningful program that is short
enough to be discovered by brute force: `cat -`, or in words:
copy stdin to stdout.The desired bytecode in Brainfuck should to match this regular expression:
```
^\{,\.[<>][-\+]\}$
```
Oh god. Let's try the actual bytecode/nibblecode:
```
^[2A][6E][7F][45CD][0189][3B]$
```
Not much better.This essentially means: "read and write, then move to a new cell and
make sure that it's not zero (otherwise we wouldn't loop back)". Since
that's only 6 instructions, and fixes only 16 bits, we need on average
65536 tries to find an ohno program that compiles to this bytecode.Of course, there's even more general versions. Can you find a regex
that captures all Brainfuck-bytecodes that are equivalent to `cat -`?(Hint: No. At least not if this Brainfuck dialect is Turing-complete,
because then you'd be solving, among other things, the [halting
problem](https://en.wikipedia.org/wiki/Halting_problem). Not only
that, you'd solve it with merely a [Finite State
Machine](https://en.wikipedia.org/wiki/Regular_expression#Expressive_power_and_compactness)!)So, after all, `cat.ohno` was computed like this, where `ohno-search.c`
says `#define OUTPUT_BYTES (6/2)` (because we want 6 instructions, each
taking up half of a byte):
```
./search | grep '^[2a][6e][7f][45cd][0189][3b] '
```
As you can see for yourself, there's lots of matches.Let's measure throughput:
```
cat /dev/zero | pv -bartT | ./ohno example/cat/cat.ohno
```
Wow! This implementation reaches roughly 1 MiB/s on my machine, which is
incredibly fast for being so shitty.## `spacecat.ohno`
The previous cat implementation uses a new cell for each character, which is bad™.
Changing `OUTPUT_BYTES` to `(8/2)` in `ohno-search.c` and recompiling
let's us do this:
```
./search | grep '^[2a][6e][7f][2a][0189][3b][0189][3b] '
```Which finds the included space-efficient cat implementation in a
reasonable time. Note that I fixed 22 bits, so this should take (on
average) 2 million guesses until something is found. In fact, the
first such program is found on attempt 1779300. It seems that
`./search` is pleasently fast for being written so carelessly.```
cat /dev/zero | pv -bartT | ./ohno example/spacecat/spacecat.ohno
```
It seems that this program only achieves 241KiB/s, which is probably
due to having to `rewind` each character. As I'm using `/dev/zero`
here, which *always* hits the worst-case, it may be a bit faster on
real-life data.## TODO
The current implementation doesn't seem to be very fast at squeezing
out several megabytes of ohno bytecode. Of course, this needs to be
improved significantly in order to write literally-large programs that
require gigabytes of bytecode, like MATLAB or AutoCAD.Calculating `cat.ohno` took only 1 second. Obviously, that's too
fast. Future versions of ohno thus should incorporate some hash
function that is more time-intensive. `bcrypt` might be the way to go.
Yes, this item is in direct contradiction to the previous point.As already mentioned, this is just an interpreter, but a true compiler
should be easily possible. This could seriously improve the execution
time for the "jump back" instruction!Are there other interesting ohno programs you can find? Something that
does something even *slightly* advanced? Maybe Caesar encoding with
wraparound?Shoot me a Pull Request! :D
(Or *just* shoot me! Aargh, the pain from writing this! Oh god! Help!)