能够自我复制的程序
是否可以制作一个 Java 程序,将其源代码打印到一个新文件中,然后对其进行编译,然后运行编译后的程序?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
更新:
好的,不妨让它自动运行。享受疯狂。运行风险自负。
是的,这是可能的,因为我确实写了它。
它不执行 RUN 部分(这太疯狂了,因为正如其他人提到的,它会导致无限循环),但这里是:Quine.java
因此,这里是如何开始疯狂的:
javac Quine.java
编译java Quine
来运行它Quine$
Quine.java
尽可能具有可读性,因此 主要 与Quine$.java
的区别在于格式化和 3x替换
。 次要差异是Quine$.java
将out
设置为Quine$$
。Quine$
将生成、编译并运行Quine$$
Quine$$
将生成、编译并运行Quine$$$
Quine$$ 将生成、编译并运行Quine$$$
code>Quine$$$
将生成、编译并运行Quine$$$$
请注意,这不会通过阅读进行任何逆向工程或作弊
.java
源代码等。Quine
是一个 quine 生成器,因为它生成不同格式的不同代码,但Quine$
几乎是一个真正的独立的 quine:它确实会自我复制,只是重新标记它Quine$$
(它会自我复制并重新标记为Quine$$$
等)。因此从技术上讲,不存在无限循环:当文件系统无法处理另一个
$
时,它最终会停止。 我能够通过强制删除所有Quine$*
文件来手动阻止这种疯狂行为,但运行风险需要您自担!!!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
So here's how to get the craziness to start:
javac Quine.java
to compilejava Quine
to run itQuine$
Quine.java
is as readable as possible, so the major difference fromQuine$.java
are formatting and the 3xreplace
. The minor difference is thatQuine$.java
hasout
set toQuine$$
.Quine$
will produce, compile and runQuine$$
Quine$$
will produce, compile and runQuine$$$
Quine$$$
will produce, compile and runQuine$$$$
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, butQuine$
is pretty much a true self-contained quine: it does reproduce itself, it just relabels itQuine$$
(which reproduces itself and relabels toQuine$$$
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 allQuine$*
files, but run at your own risk!!!是的,这是可能的。
一个简单的实现是:让源代码将其自身包含在一个字符串中,将该字符串保存到一个文件中,并用相同的字符串填充它自己的字符串(否则,由于这种递归方式,初始字符串将具有无限大小)实现),编译该文件,并运行编译后的文件(反过来,这将执行相同的操作)。
重要的实现要困难得多。
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.
当然可以 - 查看 rosetta 代码 并导航到 Quine,这是一个自无需任何外部访问即可输出其自己的源代码的参考程序。
Java 中有一个 quine 的例子。
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.
示例程序位于 < Java 能够自我复制。
输出:
Sample Program in Java which reproduces itself.
Output:
为此,您可以使用 Java 编译器 API (JSR-199)。下面是来自 JSR-199 的代码,该代码从字符串编译代码(稍微修改以使其编译)。该代码实际上将源代码从
String
编译为字节数组(即它不写入磁盘),加载它,然后通过反射执行它:MemoryFileManager.java
:用于将字符串编译为字节数组的文件管理器。ByteArrayClassLoader.java
:从字节数组加载类的类加载器。CompileFromString.java
:将所有内容包装在一起的类。这可能是一个起点(归功于原作者 Peter Van der Ahé)。
顺便说一句,您当然需要 JDK 才能使用此 API。
You could use the Java Compiler API (JSR-199) for this. Below, code from the JSR-199 that compiles code from a String (slightly modified to make it compile). The code actually compiles source code from the
String
into a byte array (i.e. it doesn't write to disk), loads it and then executes it via reflection:MemoryFileManager.java
: A file manager for compiling strings to byte arrays.ByteArrayClassLoader.java
: A class loader which loads classes from byte arrays.CompileFromString.java
: The class that wrap everything together.That could be a starting point (credits to Peter Van der Ahé, the original author).
BTW, you need of course a JDK to use this API.
我不知道你到底想要什么,但我认为 BeanShell 是你可以使用的东西。
BeanShell 是一个解释器。您可以运行未编译的 Java 代码(因此您给它一个带有代码的字符串,然后他运行它)。
当然,如果你真的想做你写的事情,运行程序的机器需要有JDK来编译你的程序。
希望这有帮助
I don't know exactly what you want, but I think BeanShell is something you can use.
BeanShell is an interpreter. You can run uncompiled Java-code (So you give it a String with code and he runs it).
Of course if you really want to do what you wrote, the machine where the program is running needs a JDK to compile your program.
Hope this helps
我认为它在 Java 中不起作用。这不会涉及覆盖正在运行的类文件吗?
假设你的程序在Quine.java中编译为Quine.class。
现在Quine.class将尝试将其输出写入Quine.java(到目前为止一切顺利),并将其编译为Quine.class。这将是一个问题,因为 Quine.class 已经在运行
I dont think it will work in Java. Wouldn't that involve overwriting a running class file.
Suppose your program is in Quine.java compiled to Quine.class.
Now Quine.class will attempt to write its output to Quine.java (so far so good), and compile it to Quine.class. This is gonna be a problem as Quine.class is already running
是的 - 不要忘记使用 JDK 而不是 JRE:
将应用程序的源代码文件与应用程序捆绑在一起。该应用程序会将源文件复制到一组新的源代码文件,编译新的源文件,将新的源代码与新的类文件捆绑到一个新的应用程序中,然后生成新的应用程序。
或
将反编译器与应用程序捆绑在一起。该应用程序将在自己的类文件上运行反编译器以生成新的源代码文件,编译新的源文件,将反编译器与新的类文件捆绑到新应用程序中,然后生成新应用程序。
Yes - don't forget to use a JDK instead of a JRE:
Bundle the app's source code files with the app. The app would copy the source files to a new set of source code files, compile the new source files, bundle the new source code with the new class files into a new app, and then spawn the new app.
or
Bundle a decompiler with the app. The app would run the decompiler on its own class files to generate new source code files, compile the new source files, bundle the decompiler with the new class files into a new app, and then spawn the new app.
这是一个使用预览文本块功能 (-source 13 --enable-preview) 的 Java Quine,其中输出的格式与输入相同:
输出:
大量评论版本:
Here's a Java Quine using preview text block feature (-source 13 --enable-preview) where output is formatted the same as input:
Output:
Heavily Commented Version: