malbolge编程语言笔记

简述

Malbolge 由 Ben Olmstead 于 1998 年发明。这种晦涩语言被认为是最复杂的编程语言。

据说 Malbolge 编程语言的作者从未使用该语言编写任何程序。Olmstead 发明该语言近两年后,Malbolge 中的 hello world 代码才出现。

这门编程语言使用反直觉的疯狂运算 (crazy operation),三基运算 (base-three arithmetic) 和自修改代码 (self-altering code) 来运行程序。

它的难度在早期的深奥语言 (esoteric languages) 之上,例如 Brainfuck 和 Befunge。

设计

Malbolge 的实现基于三元虚拟机。

在实现上,编译器停止执行 33-126 范围之外的数据 (即仅对可见字符有效)

寄存器

  • a → 累加器 (accumulator),用于写操作和标准 I/O
  • c → 代码指针 (code pointer),指向当前指令
  • d → 数据指针 (data pointer),自动递增,指向数据操作指令

指针符号

  • 寄存器 d 可以保存一个内存地址
  • [d] 是寄存器间接寻址 (register indirect)
  • [c] 是类似的

内存

数据是以三进制形式保存的(包括内存地址)。

不同的实现有不同的内存限制,存在无内存限制的版本 (Malbolge Unshackled)。

指令

Malbolge 有八个指令,通过取值 [c] 来确定要执行的指令,与 c 的值相加,得到的结果模 94,得到虚拟机对应的操作指令:

([c] + c) % 94 操作指令 用途
4 jmp [d] [d] 值赋值给 c。需要注意的是 c 还是会自增,因此执行的下一条指令是 [d] + 1 (mod 59049)
5 out a 以 ASCII 码的形式输出 a 的值到屏幕
23 in a 将输入字符以 ASCII 码的形式赋值给 a。换行符为 10;EOF 标识符是 59048。
39 rotr [d] mov a, [d] [d] 值旋转 (例如 0002111112 变为 2000211111),并将结果保存在 [d]a
40 mov d, [d] [d] 值赋值给 d
62 crz [d], a mov a, [d] [d]的值和a的值进行疯狂操作 (crazy operation),并将结果保存在 [d]a
68 nop 不做任何事。
81 end 结束程序。
default nop 不做任何事。但需要注意的是有部分 Malbolge 实现不会接受这样的操作数。

在执行每条指令后,有罪的指令 (guilty instruction) 会被加密,以便下一次执行该指令的时候不会做相同的事,除非刚刚发生了一次跳转。然后,cd 的值都加 1 并执行下一条指令。

疯狂操作 (crazy operation)

对于两个输入的三进制数,使用下表来获取结果。

例如 crz 0001112220, 0120120120 得到结果 1001022211

crz

加密

执行指令后,[c] 处的值(不添加任何内容)将替换为自身的值模 94。然后,使用下表找到结果值对应加密值,将加密值赋值给 [c]

Result Encrypted Result Encrypted Result Encrypted Result Encrypted Result Encrypted
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

Lou Scheffer 对 Malbolge 的密码分析提到了排列中的六个不同的循环。它们在这里列出:

  • 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 ...

这些循环可用于创建每次执行不同操作并最终变得重复的循环。

示例代码

Hello, World!

1
(=<`#9]~6ZY327Uv4-QsqpMn&+Ij"'E%e{Ab~w=_:]Kw%o44Uqp0/Q?xNvL:`H%c#DD2^WV>gY;dts76qKJImZkj

编辑与运行

我们可以使用在线网站来编辑和运行我们的 malbolge 程序: