Sunday, February 14, 2010

Self Printing Programs

As the topic says, self printing programs are nothing but they reproduce themselves as output. Such programs are referred as Quines from the name of the logician Willard van Orman Quine who introduced the concept.


I said an 'Ah!!!' when I heard about Quines for first time, spent more hours to find the magic behind Quines. After an analysis over a long period of time, I realized that there is no magic but logic behind it.


Its quite easier in few languages, which handle code segments as data. But in C, both are being handled as separate segments. Thus, writing quines is interesting and challenging. But if we understand the idea behind it clearly, we can easily write them in C also.


This article explains several ways of writing quines in C.


The simple and straight forward solution we usually think of is 'open the source file and print its contents'. It does not work all the times, say if we have only the executable, not the source code, this solution will not work.


Treat Code as Data


Easiest way is to treat the code statements as data to be printed. Look at the following program.


Code: C

char x[]="main() { int j; putchar(99); putchar(104); putchar(97);putchar(114); putchar(32);putchar(120); putchar(91); putchar(93);putchar(61); putchar(34); for(j=0; j; main() { int j; putchar(99); putchar(104); putchar(97); putchar(114); putchar(32); putchar(120);putchar(91); putchar(93); putchar(61); putchar(34); for(j=0; j(x); ++j) putchar(x[j]);putchar(34); putchar(59); putchar(10); for(j=0 ; j(x); ++j) putchar(x[j]); putchar(10); }

Quote:

Author: Dave

Type the above program in just two lines, one for declaration of x and another for the main. The string x has the whole program instructions. Design your main to print the string which has the code statemets. The trickest part of writing quines is 'the statement which is used to print the code must also be printed'.

Lets see how it works.


The putchar statements before the first for loop print till

Code:

char x[] =”

The first for loop print the string contents.

Code:

main() { int j; putchar(99); putchar(104); putchar(97); putchar(114); putchar(32); putchar(120);putchar(91); putchar(93); putchar(61); putchar(34); for(j=0; j

The putchars in between the for loops print

Code:

“;

We have printed the declaration of x so far. The only task is left for us, to print the main program. This is taken care by the second for loop. The last putchar adds a newline into the output.

Quote:

The putchar statements recieves ASCII values of the characters. Replace the ASCII values and try with actual characters, ie replace putchar(99) by putchar('c'). You will come to know the difficulty of using characters directly.

Format specifiers


Another way of writing them is with the aid of format specifiers intelligently.

Code: C

main(){char q=34,n=10,*a="main(){char q=34,n=10,*a=%c%s%c;printfa,q,a,q,n);}%c";printf(a,q,a,q,n);}

Quote:

Author: John Burger, David Brill, Filip Machi0

The above program is one liner, the statement has to be focussed is printf only. It's not difficult to understand that the following contents are printed.

Code:

main(){char q=34,n=10, *a=

Now, replace the %c with double quotes(“) and %s with the string a and so on.... Hence the resultant printf statement will be as follows,

Code: C

printf(“main(){char q=34,n=10,*a=%c%s%c;printf(a,q,a,q,n);}%c”,q,”main(){char q=34,n=10,char *a=%c%s%c;printf(a,q,a,q,n)}”,q,n);

Macros


Here is another way of writing is using macros. The fact behind it upon substitution of macro, we will get a printf statement which dumps the actual code.

Code: C

#define T(a) main(){printf(a,#a);} T("#define T(a) main(){printf(a,#a);}\nT(%s)")

Quote:

Author: Joe Miller

Expand the macro for to understand the execution..


Palindromic Quines


It is awesome when I come to know about the following program. The program itself is palindrome as well as quine.

Code: C

/**/char q='"',*a="*//**/char q='%c',*a=%c%s%c*/};)b(stup;]d[b=]d-852[b)--d(elihw;)q,a,q,q,2+a,b(ftnirps{)(niam;031=d tni;]952[b,",b[259];int d=130;main(){sprintf(b,a+2,q,q,a,q);while(d--)b[258-d]=b[d];puts(b);}/*c%s%c%=a*,'c%'=q rahc/**//*"=a*,'"'=q rahc/**/

Quote:

Author: Dan Hoey

Winner of Worst Abuse of the Rules


Given below has won the 'Worst Abuse of the Rules Award' in 1994 Obfuscated C Contest.

Code: C

main(){char*a="main(){char*a=c%s%c%;printf(a+42,34,a,34);};)43,a,43,24+a(ftnirp;%c%s%c=a*rahc{)(niam";printf(a+42,34,a,34);}

Quote:

Author: smr

For more quines in your favorite languages, refer http://www.nyx.net/~gthompso/quine.htm


Here are my attempts

Type these programs as it is given... Don't even add/delete a single NEWLINE or SPACE or TAP characters

Code: C

// First Program #include h> main() { char *a = "#include %cmain()%c{%c%cchar *a = %c%s%c;%c%cprintf(a,10,10,10,9,34,a,34,10,9,10,10);%c}%c"; printf(a,10,10,10,9,34,a,34,10,9,10,10); } // Second Program #define print(s) (#s) main() { char *a = "printf(print(#define print(s) (#s)%cmain()%c{%c%cchar *a=%c%s%c;%c%c%s%c}%c),10,10,10,9,34,a,34,10,9,a,10,10);"; printf(print(#define print(s) (#s)%cmain()%c{%c%cchar *a=%c%s%c;%c%c%s%c}%c),10,10,10,9,34,a,34,10,9,a,10,10); } // Third Program #define T(a,b) strcat(a,b) main() { char s1[256] = "#define T(a,b) strcat(a,b)%cmain()%c{%c", s2[256] = "%cchar s1[256] = %c%s%c, s2[256] = %c%s%c, s3[256] = %c%s%c;%c%c%cprintf(T(s1,s2),10,10,10,9,34,s3,34,34,s2,34,34,s3,34,10,10,9,10,10);%c}%c", s3[256] = "#define T(a,b) strcat(a,b)%cmain()%c{%c"; printf(T(s1,s2),10,10,10,9,34,s3,34,34,s2,34,34,s3,34,10,10,9,10,10); }

I hope this article gives much better hopes in writing quines. To conclude, with little intelligency all of us can write quines.

No comments: