如何编写一个打印自身源代码的程序

一个程序,在没有任何外部输入的情况下,打印自身的源代码,这类程序在英文里有一个专门的称呼,叫做Quine,之所以叫这个名字,是为了纪念美国哲学家及逻辑学家Willard Van Orman Quine。

问题分析

首先要搞清楚问题的约束条件,即程序不能有任何的外部输入,否则可以通过把文件路径传入程序来获取源文件再打印出来,这种情况被看作是作弊。

我们以Python2作为示例语言。我们知道 printprint 关键字能够将内容输出到控制台:它实际上是一个函数,接受一个入参,并把它打印到控制台。但是我们的程序是没有输入的,因此,最最简单直观的思路,我们的程序(假设为 <P><P> )至少应该包含两个语句(假设为 <A>,<B><A>,<B> ),即:

<P> := <A><B>

他们分别有如下职责:

<A> : 定义<B> (或者说在程序没有输入的情况下要为print函数创造输入) <B> : 首先要打印<A>的源代码,其次要把自身的源代码打印出来

用中文来说,可以是:

把以下的话抄一遍后再抄在引号里“把以下的话抄一遍后再抄在引号里”

基本上编写一个Quine的精髓就在上面这段话里。

在Python中有一个 %r\%r ,它的意思就是调用对象的 repr()repr() 方法后替换本身在字符串中的位置,对于字符串对象,会保留其本身的引号(这点在我们实现Quine的时候会减少很多麻烦)。我们可以借助它实现一个最简单的Quine:

s = s = %r\nprint s %% s print s % s

程序第一行我们定义了一个变量 ss ,在第二行我们首先将 ss 的字面量传进 ss 用于生成本程序的完整代码随即打印它。如果不借助 %r\%r 程序会复杂一些,但基本的思路是差不多的:

# -*- coding:utf-8 -*- q = chr(39) # 定义单引号 n = chr(10) # 定义换行符 s = # -*- coding:utf-8 -*-%sq = chr(39) # 定义单引号%sn = chr(10) # 定义换行符%ss = %s%s%s%sprint s %% (n, n, n, q, s, q, n) print s % (n, n, n, q, s, q, n)

如何使程序输出MD5等于自身源代码的MD5

这个其实和上面的问题是等价的,能够输出自身源代码,当然也能输出自身的MD5了:

import hashlib m = hashlib.md5() s = import hashlib\nm = hashlib.md5()\ns = %r\nm.update(s %% s)\nprint m.hexdigest() m.update(s % s) print m.hexdigest()

测试一下:

zhaoyuyu@FISHZHAO-MB0 demo % md5sum quine.py 0499c0b4e56111ba6587db5624f21345 quine.py zhaoyuyu@FISHZHAO-MB0 demo % python quine.py 0499c0b4e56111ba6587db5624f21345

完美!

拓展阅读:

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片