Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Quine Whine

by AgentM (Curate)
on Mar 06, 2001 at 04:12 UTC ( [id://62389]=perlmeditation: print w/replies, xml ) Need Help??

One of my assistants has been a assigned a homework (*gasp* I used the "H" word- quick --!) in which he deals with quines. A quine is simply a program that prints it own source. Now I say "simply", but coming up with one, even just a short one, is an exercise in itself. As Ken Thompson adeptly points out in Reflections on Trusting Trust(1984), "If you have never done this, I urge you to try it on your own. The discovery of how to do it is a revelation that far surpasses any benefit obtained by being told how to do it." (He also says, "...FORTRAN was the language of choice for the same reason that three-legged races are popular" but that's another story.)

I certainly did find out he was right. In his paper, he gives some unsatisfying examples and suddenly I had to know more...

Thus, I ended up at

The Quine Page

Why is this in the maximum font size you ask? Well, that's because you haven't clicked on it yet. I'll wait now while you do that...

Ok. Hi. Welcome back. Now that you've browsed through at least a few quines, you have a general idea of how they work. I'd say the easiest one to understand is

Author: Travis Emmit $s="7072696e742724733d22272e24732e225c223b5c6e222e7061636b22482a222c24 +733b0a"; print'$s="'.$s."\";\n".pack"H*",$s;
This quine has simply hexidecimalized its source and it prints it out. That's all fine and dandy until you get to
Author: Allan M. Due #!/usr/local/bin/perl -w use strict; $_ = q(s|(.*)|print "#!/usr/local/bin/perl -w\nuse strict;\n\$_ = q(",$1,");\n",$1,";\n"|e); s|(.*)|print "#!/usr/local/bin/perl -w\nuse strict;\n\$_ = q(",$1,");\n",$1,";\n"|e;
In his attempt to get it to work, it looks like it automatically turned in obfuscation. As you know, our very own camel code makes four camels out one harmless looking camel. This is not exactly a quine, but a quine may also do impressive stuff with its output. The general method to use is 'initially store the program in a string for later printing' (after you use that same code). It even looks like an eval or two may come in handy for these jokers.

Believe it or not, quines, which seem to have a chicken-egg relationship, are useful in the making of compilers since the compiler needs to read sequences of the code it was written in. The C compiler was written in C (refer to Thompson Presentation). Thompson elaborates by describing how bugs could be written into compilers to create potentially untraceable hacks for security breachs (the topic of his presentation).

That said, I hope I've captured your interest. Perl seems to be a premiere language for developing quines (along with those cool PostScript examples). Feel free to include some cool links or examples of quines below. Oh, and for Petruchio, I include the obligatory link to the JavaScript quine page.

AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.

Replies are listed 'Best First'.
Re (tilly) 1: Quine Whine
by tilly (Archbishop) on Mar 06, 2001 at 12:18 UTC
    I am amazed that they left out the shortest Perl Quine. Here it is: Not much to it, is there? :-)

    (Think very, very carefully before voting. I did post a valid Perl quine. It is the shortest that there is. And is so short that it is very, very easy to miss. d/l it if you don't believe me.)

      Oh goodness. You even put it in <CODE> tags. I just had to check the source to see if you were indeed that silly. It is a marvelous piece of code though. ;)

      -Lexicon

Re (tilly) 1 (explain): Quine Whine
by tilly (Archbishop) on Mar 06, 2001 at 20:09 UTC
    For those who are puzzled by quines, the following page has a good explanation of why they always exist, and exactly how to go about writing one. They are much easier to write in languages which do not require fixed chunks of text, have abundant quoting facilities, are good at string manipulation, and support eval. You will note that Perl has all of these characteristics...

    The basic idea is that you have a program that consists of source and data, where the data can be expanded out into source, and also be reproduced as data. Which is why it is nice to now have fixed source that has to be there, is nice to have good ways to quote the data, is nice to be able to manipulate the data, and why it is a bonus to be able to turn data into source and then eval it.

    I do urge people to write their own. It is surprisingly easy to do, and the process is very instructive.

Re (tilly) 1: Quine Whine
by tilly (Archbishop) on Mar 06, 2001 at 22:16 UTC
    Hmmm...people don't seem to be interested in making them. Ah well. Here is a quine that shows a standard form that you can usually get to work...
    # This is a quine. $c = "# This is a quine. "; $t = q(-c$c = "-c"; $t = q(-t); # Note the repeated text here. This appears both in data # and in source. Anything you want can go here as long # as it repeats and you do not interfere with these actions... # Substitute the variables back into the data. If you do # not like symbolic refs, you could use a hash instead, same # diff. This substitution builds source out of data. $t =~ s/-(\w+)/${$1}/g; # Since data is now source, just print it and we are done. print $t; ); # Note the repeated text here. This appears both in data # and in source. Anything you want can go here as long # as it repeats and you do these actions... # Substitute the variables back into the data. If you do # not like symbolic refs, you could use a hash instead, same # diff. This substitution builds source out of data. $t =~ s/-(\w+)/${$1}/g; # Since data is now source, just print it and we are done. print $t;
    Of course it is also quite possible to make jokes that are quines. In fact I already did with the rather degenerate shortest one above. And here is another joke quine:
    # This is a quine two :-) undef $/; $_ = <DATA>; print; print; __DATA__ # This is a quine two :-) undef $/; $_ = <DATA>; print; print; __DATA__
    (Come on, give it a try. Quines are really quite fun. :-)

      Well, here is an old standby:

      $_=q(print qq(\$_=q($_);eval\n));eval

      And here is a clever one I originally saw ages ago on clpm (posted by mjd I think, but I could be wrong about that). Save the following line to a file named "/tmp/p" and run as: perl /tmp/p

      Illegal division by zero at /tmp/p line 1.
Re: Quine Whine
by CiceroLove (Monk) on Mar 06, 2001 at 08:43 UTC
    I rememebr not too long ago someone doing something along the lines of:
    <PSEUDO-CODE>
    __DATA__ print DATA;

    I tried searching for it here but it didn't come up. I thought it one of the more clever ways to accomplish a quine.

    CiceroLove
    Fates! We will know your pleasures: That we shall die, we know; 'Tis but the time, and drawing days out, that men stand upon. - Act III,I, Julius Caesar

      Maybe you are thinking of:

      seek *DATA, 0, 0; print <DATA>; __DATA__

      Prints:

      seek *DATA, 0, 0; print <DATA>; __DATA__
      Perl is the programming world's equivalent of English
Re: Quine Whine
by mr.nick (Chaplain) on Mar 06, 2001 at 10:01 UTC
    Wouldn't
    #!/usr/bin/perl open IN,$0; print while <IN>; close IN;
    also qualify? Or is that not obsfuscated enough?

      Nope. Doesn't count, at least according to the definition on the quine page listed above:

      I define a quine as a program which reproduces itself on an output device without inputting its source.

      I think that most people who care about this would agree with the definition above. You could redefine "quine"; your task would then be to convice those who care that your definition is better. :-)

      p.s. It doesn't have anything to do with obfuscation...

Re: Quine Whine
by ambrus (Abbot) on Sep 30, 2014 at 21:08 UTC
Re: Quine Whine
by strfry() (Monk) on Oct 19, 2001 at 21:52 UTC
    this is just MHO, but this one seems a bit easier to understand... (5th example down on the quine page's perl quine page and changed to use strict;and use warnings;):
    #!/usr/bin/perl use warnings; use strict; $_=<<'eof';eval $_; print "#!/usr/bin/perl\nuse warnings;\nuse strict;\n\$_=<<'eof';eval \ +$_;\n${_}e of\n" eof
    strfry()

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://62389]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (7)
As of 2024-04-19 09:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found