我最近发现了这个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字符串%s39的第四个参数printf%c10是最后%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) ^^