Self Printing Programs

Discussion in 'C' started by dharmaraj.guru, Nov 22, 2007.

  1. dharmaraj.guru

    dharmaraj.guru New Member

    Joined:
    Oct 23, 2007
    Messages:
    16
    Likes Received:
    0
    Trophy Points:
    0
    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:
    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<strlen(x); ++j)putchar(x[j]);putchar(34); putchar(59); putchar(10); for(j=0; j<strlen(x); ++j) putchar(x[j]);putchar(10); }";
    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<strlen(x); ++j) putchar(x[j]);putchar(34); putchar(59); putchar(10); for(j=0 ; j<strlen(x); ++j) putchar(x[j]); putchar(10); }
    
    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<strlen(x); ++j) putchar(x[j]);putchar(34); putchar(59); putchar(10); for(j=0 ; j<strlen(x); ++j) putchar(x[j]); putchar(10); }
    
    
    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.

    Format specifiers



    Another way of writing them is with the aid of format specifiers intelligently.
    Code:
    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);}
    
    
    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:
    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:
    #define T(a) main(){printf(a,#a);}
    T("#define T(a) main(){printf(a,#a);}\nT(%s)")
    
    
    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:
    /**/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/**/
    
    

    Winner of Worst Abuse of the Rules



    Given below has won the 'Worst Abuse of the Rules Award' in 1994 Obfuscated C Contest.
    Code:
    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);}
    
    
    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:
    // First Program
    #include <stdio.h>
    main()
    {
    	char *a = "#include <stdio.h>%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.
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  4. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice