Question

I found this quine recently

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);

And I just can't get my head around it. I've found no explanation on google/SO for this particular one, so I'm hoping that someone could explain to me how that thing works :-)

Was it helpful?

Solution 2

Look at printf parameters and substitute them by hand,

(39 is single quote, ', and 10 is newline \n when interpreted as %c) so $a which start as

$a=%c%s%c;printf($a,39,$a,39,10);%c

becomes (replaced chars marked below with ^)

$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)

and finally

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);\n
                                             (last %c replaced) ^^ 

OTHER TIPS

This code is consisted of two lines.

A variable assignment:

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';

And a printf:

printf($a,39,$a,39,10)

First of all let's learn a few things about printf. If you check the sprintf documentation you will see that printf('%c',39) will print the 39th character which is ', while the printf('%c',10) is a newline \n. Another thing to keep in mind is that printf takes a list of parameters which means that printf('%s%s','foo','bar') will print foobar.

So now it should be clear that printf($a,39,$a,39,10) takes the format from $a and does the following 4 conversions (equal to the number of % signs in the $a string)

  • uses the 2nd argument 39 for the 1st occurrence of %c (check the $a variable),
  • then it uses the string $a for %s
  • the 4th argument 39 of the printf for the next %c
  • and finally the 10 for the last %c

which results in a copy of its own source code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top