Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programs that reproduces itself

Tags:

java

quine

Is it possible to make a Java program that prints its source code to a new file, and compiles it, and runs the compiled program?

like image 963
Ming-Tang Avatar asked Apr 11 '10 16:04

Ming-Tang


3 Answers

Update:

Okay, might as well make it autorun. Enjoy the madness. Run at your own risk.


Yes it's possible, because I actually wrote it up. It doesn't do the RUN part (that's just too crazy, because as others have mentioned, it will cause an infinite loop), but here it is: Quine.java

import java.io.*;
public class Quine {
   public static void main(String[] args) throws Exception {
      char q = 34;
      String out = "Quine$";
      String text = (
         "import java.io.*; " +
         "public class [OUT] { " +
           "public static void main(String[] args) throws Exception { " +
             "char q = 34; String out = `[OUT]$`; String text = `[TEXT]`; " +
             "PrintWriter pw = new PrintWriter(out + `.java`); " +
             "pw.format(text, 34, out, text); " +
             "pw.close(); Runtime runtime = Runtime.getRuntime(); " +
             "runtime.exec(`javac ` + out + `.java`).waitFor(); " +
             "runtime.exec(`java ` + out); " +
           "} " +
         "}"
      ).replace("`", "%1$c").replace("[OUT]", "%2$s").replace("[TEXT]", "%3$s");
      PrintWriter pw = new PrintWriter(out + ".java");
      pw.format(text, 34, out, text);
      pw.close();
      Runtime runtime = Runtime.getRuntime();
      runtime.exec("javac " + out + ".java").waitFor();
      runtime.exec("java " + out);
   }
}

So here's how to get the craziness to start:

  • javac Quine.java to compile
  • java Quine to run it
    • It will produce, compile and run Quine$
  • I've made sure Quine.java is as readable as possible, so the major difference from Quine$.java are formatting and the 3x replace. The minor difference is that Quine$.java has out set to Quine$$.
  • Quine$ will produce, compile and run Quine$$
  • Quine$$ will produce, compile and run Quine$$$
  • Quine$$$ will produce, compile and run Quine$$$$
  • ...

Do note that this doesn't do any reverse-engineering or cheat by reading the .java source code, etc. Quine is a quine-generator because it produces a different code differently formatted, but Quine$ is pretty much a true self-contained quine: it does reproduce itself, it just relabels it Quine$$ (which reproduces itself and relabels to Quine$$$ etc).

So technically there's no infinite loop: it will eventually come to a halt when the file system can't handle another $. I was able to manually stop the madness by forcefully deleting all Quine$* files, but run at your own risk!!!

like image 99
polygenelubricants Avatar answered Oct 22 '22 12:10

polygenelubricants


Yes, it is possible. A trivial implementation would be: have the source code contain itself in a string, save the string to a file and fill its own string with the same string (otherwise, the initial string would be of infinite size, due to the recursive manner of this implementation), compile the file, and run the compiled file (which will, in turn, do the very same).

Non-trivial implementations are significantly harder.

like image 45
M.A. Hanin Avatar answered Oct 22 '22 14:10

M.A. Hanin


Sure it works - Have a look at rosetta code and navigate to Quine, which is a self-referential program that can, without any external access, output its own source.

There's one example for a quine in Java.

like image 42
Andreas Dolk Avatar answered Oct 22 '22 12:10

Andreas Dolk