導入
Malbolge は、1998 年に Ben Olmstead によって発明されたパブリック ドメイン プログラミング言語であり、ダンテの地獄篇に登場する地獄の 8 番目のサークルであるMalebolgeにちなんで名付けられました。
Malbolgeの特徴は、それが可能な限り最悪の (最も難しくてエキゾチックな) プログラミング言語になるように設計されていることです。ただし、理解を難しくするために使用されるトリックの一部は簡略化することができます。

マルボルヘでのプログラミング
マルボルゲは登場当時非常にわかりにくかったため、最初のマルボルゲ プログラムが登場するまでに 2 年かかりました。このプログラムは人間によって書かれたものではなく、Andrew Cooke によって設計されたビーム探索アルゴリズムによって生成され、 Lispに実装されました。
2000 年 8 月 24 日、アンソニー ユーハスは自身のブログで「マルボルゲを棒で倒し、その秘密をマスターした」と発表し、さまざまなフレーズを表示する 3 つのマルボルゲ プログラムの形で証拠を提供しました。ただし、そのテクニックについては明かさなかった。
その後、Lou Scheffer が Malboge の暗号解読を投稿し、その入力を出力にコピーするプログラムを提供しました。
オルムステッドはマルボルゲが無限の記憶を除いてチューリング完全であると信じていた。 Malbolge でループを実装できるかどうかについて興味深い議論がありました。最初の非終端ループが導入されるまでに何年もかかりました。
2004 年 8 月 17 日、Tomasz Wegrzanowski は、さまざまな文字列を表示する Malbolge プログラム ジェネレーターを作成しました。彼によると、コツはジャンプのことを忘れ、D レジスタをメモリ内の低い位置に保持し、必要なレジスタが A レジスタに含まれるまで NOP、ROT、および Crazy 演算をランダムに実行することです。この手法で作成されたプログラムは、Anthony のプログラムよりもはるかに大規模です。
マルボルヘの簡単なプログラム
Malbolge は、トライナリ仮想マシン、Malbolgeインタプリタ用のマシン言語です。正しく動作する Malbolge プログラムを作成するのに役立つように、標準インタープリタがどのように動作するかを以下に説明します。
注意事項
- 標準インタープリタと公式仕様は完全には一致しません。
- これは、インタプリタのソース コードの簡略化された説明です。不必要な暗号化と減算の手順を回避し、アセンブリ言語を導入しています。
- 修正する前に、単に異常であるだけでなく、実際に技術的に間違っていることを確認してください。

記録
Malbolge には、他の言語の変数に似た 3 つのレジスタa 、 c 、およびd があります。プログラムが開始されるとき、これら 3 つのレジスタの値は0です。これは特別です。それは序数カウンタです (つまり、現在の命令を指します)。
ポインタ表記
[d] は、 dの値がメモリアドレスであることを意味します。 [d] は、このアドレスに格納されている値です。 [c]も同様です。
メモリ
仮想マシンには 59049 のメモリ位置があり、それぞれに 10 桁の 3 進数を保持できます。各メモリ位置には 0 ~ 59048 のアドレスがあり、0 ~ 59048 の値を保持できます。59049 に達した値は 0 に置き換えられます。
Malbolge プログラムが開始される前に、メモリの最初の部分がプログラムで埋められます。プログラム内のすべての空白は無視され、プログラミングをより困難にするために、プログラム内の他のすべては次の命令のいずれかとして開始する必要があります。
メモリの残りの部分は、前の 2 つのアドレス ( [m] = crz [m – 2]、[m – 1] ) に対する Crazy 演算 (以下を参照) を使用して埋められます。このようにして埋められたメモリは 12 アドレスごとに繰り返されます (個々の 3 進数字は 3 つまたは 4 つのアドレスごとに繰り返されるため、3 進数字のグループは 12 アドレスごとに繰り返されることが保証されます)。
説明書
Malbolge には 8 つの命令があります。 Malbolge は、 [c]の値を取得し、それにcの値を加算し、数値が 94 未満になるまで 94 を減算することによって、実行する命令を見つけます。最終結果は、インタプリタに何を実行する必要があるかを伝えます。
| ([c] + c) の値 % 94 | 指示が示されています | 説明 |
|---|---|---|
| 4 | jmp[d]+1 | [d]の値に 1 を加えた値が、Malbolge がジャンプして命令の実行を開始する場所です。 |
| 5 | アウト | aの値を ASCII 文字として画面に表示します。 |
| 23 | で | に文字を ASCIIコードとして入力します。改行はコード10です。ファイル終了条件はコード59048です。 |
| 39 | ローター[d] 移動 a, [d] | 値を 3 進数の[d]に回転します (000211111 2は2 000211111 になります)。結果を[d]とa の両方に格納します。 |
| 40 | mov d, [d] | [d]の値をdにコピーします。 |
| 62 | crz [d]、a 移動 a, [d] | [d]の値とaの値を使用して Crazy 操作 (下記を参照) を実行します。結果を[d]とa の両方に格納します。 |
| 68 | いいえ | 何もしません。 |
| 81 | 終わり | プログラムを終了します。 |
| 他の値は68 : nothing のようなものです。これらの値は、ロード中のプログラムでは許可されませんが、後で許可されます。 | ||
各命令が実行された後、現在の命令は暗号化され (以下を参照)、ジャンプが到着したばかりでない限り、次回同じことを行わないようにします。一方、マルボルゲはジャンプ直後に、ジャンプする直前の命令を暗号化します。その後、 cとdの値が 1 ずつインクリメントされ、次の命令が実行されます。

オペレーション・クレイジー
両方の入力の各 3 進数について、次の表を使用して結果から 3 進数を取得します。たとえば、 crz 0001112220、0120120120 は1001022211 となります。
| くそー | エントリー 2 | |||
|---|---|---|---|---|
| 0 | 1 | 2 | ||
| エントリー1 | 0 | 1 | 0 | 0 |
| 1 | 1 | 0 | 2 | |
| 2 | 2 | 2 | 1 | |
暗号化
命令の実行後、 [c]の値 (何も加算せず) が 94 未満になるまで 94 から減算されます。その後、結果は次の 2 つの同等の方法のいずれかで暗号化されます。
方法 1
以下の結果を見つけてください。最下位文字の ASCII コードを[c]に格納します。
000000000001111111111222222222333333333444444445555555566666666777777778888888889999 012345678901234567890123456 123456789012345678901234567890123456789012345678901234567890123 --------------------------------------------- ----------------------------------------------- 9m<。 Vac `uY*MK'X~xDl}REokN:#?G"i@5z]&gqtyfr$(we4{WP)H-Zn,[%\3dL+Q;>U!pJS72FhOA1CB6v^=I_0/8|jsb方法 2
以下の結果を見つけてください。暗号化されたバージョンを[c]に保存します。
| 結果 | 形 | 結果 | 形 | 結果 | 形 | 結果 | 形 | 結果 | 形 |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 57 | 19 | 108 | 38 | 113 | 57 | 91 | 76 | 79 |
| 1 | 109 | 20 | 125 | 39 | 116 | 58 | 37 | 77 | 65 |
| 2 | 60 | 21 | 82 | 40 | 121 | 59 | 92 | 78 | 49 |
| 3 | 46 | 22 | 69 | 41 | 102 | 60 | 51 | 79 | 67 |
| 4 | 84 | 23 | 111 | 42 | 114 | 61 | 100 | 80 | 66 |
| 5 | 86 | 24 | 107 | 43 | 36 | 62 | 76 | 81 | 54 |
| 6 | 97 | 25 | 78 | 44 | 40 | 63 | 43 | 82 | 118 |
| 7 | 99 | 26 | 58 | 45 | 119 | 64 | 81 | 83 | 94 |
| 8 | 96 | 27 | 35 | 46 | 101 | 65 | 59 | 84 | 61 |
| 9 | 117 | 28 | 63 | 47 | 52 | 66 | 62 | 85 | 73 |
| 10 | 89 | 29 | 71 | 48 | 123 | 67 | 85 | 86 | 95 |
| 11 | 42 | 30 | 34 | 49 | 87 | 68 | 33 | 87 | 48 |
| 12 | 77 | 31 | 105 | 50 | 80 | 69 | 112 | 88 | 47 |
| 13 | 75 | 32 | 64 | 51 | 41 | 70 | 74 | 89 | 56 |
| 14 | 39 | 33 | 53 | 52 | 72 | 71 | 83 | 90 | 124 |
| 15 | 88 | 34 | 122 | 53 | 45 | 72 | 55 | 91 | 106 |
| 16 | 126 | 35 | 93 | 54 | 90 | 73 | 50 | 92 | 115 |
| 17 | 120 | 36 | 38 | 55 | 110 | 74 | 70 | 93 | 98 |
| 18 | 68 | 37 | 103 | 56 | 44 | 75 | 104 |

暗号化のサイクル
ルー・シェファーによるマルボルゲの暗号解読では、暗号化における 6 つの異なるサイクルについて言及しています。それらはここにリストされています:
- 33 ⇒ 53 ⇒ 45 ⇒ 119 ⇒ 78 ⇒ 49 ⇒ 87 ⇒ 48 ⇒ 123 ⇒ 71 ⇒ 83 ⇒ 94 ⇒ 57 ⇒ 91 ⇒ 106 ⇒ 77 ⇒ 65 ⇒ 59 ⇒ 92 ⇒ 115 ⇒ 82 ⇒ 118 ⇒ 107 ⇒ 75 ⇒ 104 ⇒ 89 ⇒ 56 ⇒ 44 ⇒ 40 ⇒ 121 ⇒ 35 ⇒ 93 ⇒ 98 ⇒ 84 ⇒ 61 ⇒ 100 ⇒ 97 ⇒ 46 ⇒ 101 ⇒ 99 ⇒ 86 ⇒ 95 ⇒ 109 ⇒ 88 ⇒ 47 ⇒ 52 ⇒ 72 ⇒ 55 ⇒ 110 ⇒ 126 ⇒ 64 ⇒ 81 ⇒ 54 ⇒ 90 ⇒ 124 ⇒ 34 ⇒ 122 ⇒ 63 ⇒ 43 ⇒ 36 ⇒ 38 ⇒ 113 ⇒ 108 ⇒ 39 ⇒ 116 ⇒ 69 ⇒ 112 ⇒ 68 ⇒ 33 …
- 37 ⇒ 103 ⇒ 117 ⇒ 111 ⇒ 120 ⇒ 58 ⇒ 37 …
- 41 ⇒ 102 ⇒ 96 ⇒ 60 ⇒ 51 ⇒ 41 …
- 42 ⇒ 114 ⇒ 125 ⇒ 105 ⇒ 42 …
- 50 ⇒ 80 ⇒ 66 ⇒ 62 ⇒ 76 ⇒ 79 ⇒ 67 ⇒ 85 ⇒ 73 ⇒ 50 …
- 70 ⇒ 74 ⇒ 70 …
これらのサイクルを使用して、毎回異なることを実行し、最終的には繰り返しになるループを作成できます。 Lou Scheffer はこのアイデアを使用して、ユーザーが入力として与えたものをすべて繰り返す Malbolge プログラム (以下にリンクされている彼の暗号解析に含まれています) を作成しました。
