我最近发现了这个quine
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);
我就是无法理解它。我在 google/SO 上找不到这个特定的解释,所以我希望有人可以向我解释这件事是如何工作的 :-)
这段代码由两行组成。
变量赋值:
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';
还有一个printf:
printf($a,39,$a,39,10)
首先让我们了解一些关于printf
. 如果您查看sprintf 文档,您将看到printf('%c',39)
将打印第 39 个字符,即是'
,而 theprintf('%c',10)
是换行符\n
。要记住的另一件事是,它printf
需要一个参数列表,这意味着printf('%s%s','foo','bar')
将打印foobar
.
所以现在应该清楚的是,printf($a,39,$a,39,10)
从格式中获取$a
并进行以下 4 次转换(等于字符串中的%
符号数)$a
39
用于第一次出现%c
(检查$a
变量),$a
字符串%s
39
的第四个参数printf
%c
10
是最后%c
这会导致它自己的源代码的副本。
查看printf
参数并手动替换它们,
(39
是单引号, '
, 并且在解释10
为时是换行符) 所以开头为\n
%c
$a
$a=%c%s%c;printf($a,39,$a,39,10);%c
变为(用 替换下面标记的字符^
)
$a='%s%c;printf($a,39,$a,39,10);%c
^ (first %c replaced)
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c%c;printf($a,39,$a,39,10);%c
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (%s replaced)
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);%c
^ (second %c replaced)
最后
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);\n
(last %c replaced) ^^