输出自己的 MD5 值的程式
这样的程式存在其实不太意外
毕竟有无限多种程式,但 MD5 的值是有限的
让我意外的是要找出这样的程式不需要爆搜
而是可以简单的建构出来
参考 http://www.madore.org/~david/computers/quine.html
写了一个 Python3 版本的
from hashlib import md5
data = """
m = md5()
m.update(b"from hashlib import md5\\n\\n")
m.update(b"data = \\"\\"\\"")
for ch in data:
m.update(ch.encode() if ch != '\\\\' else b"\\\\\\\\")
m.update(b"\\"\\"\\"\\n")
m.update(data.encode())
print(m.hexdigest())
"""
m = md5()
m.update(b"from hashlib import md5\n\n")
m.update(b"data = \"\"\"")
for ch in data:
m.update(ch.encode() if ch != '\\' else b"\\\\")
m.update(b"\"\"\"\n")
m.update(data.encode())
print(m.hexdigest())
(结尾有换行)
这个程式码的 MD5 是 a509ddcd25429679ea474625b7cc39c5
执行之后的输出也的确是这个值
可以看到其实在上面的程式把 MD5 换成其他的 function 也没有差
查了一下后发现有这样一个定理:
https://en.wikipedia.org/wiki/Kleene%27s_recursion_theorem
Rogers's fixed-point theorem.
If F is a total computable function,
there is an index e such that φ_e = φ_{F(e)}.
可以想成是假如 F 可以将一个程式码转成另一个程式码
那就一定会有程式码在转之前 (e) 和转之后 (F(e)) 的行为是一样的
这一开始是拿来造出会印出自己本身的程式
假如把 F 设为“输入 x, 输出会印出 MD5(x) 的程式码”
根据这个定理,就一定有程式码 p 他的行为和 F(p)一样
也就是印出 MD5(p),他自己的 MD5 值
然后这个定理的证明是 constructive,所以可以照着他的证明建构出这样的程式
好酷喔