16字节的Python可以编译为32 TB的字节码(2016)

2021-02-17 18:23:54

\\\ begingroup \ $您可能熟悉zip炸弹,XML炸弹等。简单来说,它们是(相对)较小的文件,当由朴素的软件解释时,它们会产生巨大的输出。这里的挑战是以同样的方式滥用编译器。

编写一些占用512个字节或更少字节的源代码,并将其编译成一个占用最大可能空间的文件。最大的输出文件胜出!

编译的输出必须是ELF文件,Windows Portable可执行文件(.exe)或JVM或.Net CLR的虚拟字节码(如果需要,其他类型的虚拟字节码也可能没问题) 。更新:Python的.pyc / .pyo输出也算在内。

如果您不能将选择的语言直接编译为其中一种格式,则也可以先进行编译再进行编译(更新:您可以多次进行编译,只要您从未多次使用同一语言即可) )。

您的源代码可以包含多个文件,甚至可以包含资源文件,但是所有这些文件的总大小不能超过512个字节。

除了源文件和选择语言的标准库之外,您不能使用任何其他输入。如果支持静态链接标准库,则可以。具体来说,没有第三方库或OS库。

必须可以使用一个或多个命令来调用您的编译。如果在编译时需要特定的标志,这些标志将计入您的字节数限制(例如,如果您的编译行是gcc bomb.c -o bomb -O3 -lm,则-O3 -lm部分(7字节)将被计入(请注意,前导空间不算在内)。

环境取决于您,但为了使此可验证性感兴趣,请坚持使用最新的(即可用的)编译器版本和操作系统(并显然指定您使用的是哪个)。

它必须编译时没有错误(警告是可以的),并且崩溃会使编译器不起作用。

您的程序实际执行的操作无关紧要,尽管它不可​​能是恶意的。它甚至不必启动。

产生一个9228字节的文件。源的总大小为17 + 3(对于-pg)= 20字节,这很容易在大小限制内。

产生一个8464字节的文件。此处的总输入为143字节(因为@lang_c是awib的默认值,因此不需要将其添加到源文件中,并且两个命令中都没有特殊标志)。

还要注意,在这种情况下,临时的bomb.c文件为802字节,但这不会计入源大小或输出大小。

如果实现了超过4GB的输出(也许有人找到了一个完整的预处理器),那么竞争将是争夺产生至少该大小文件的最小源(测试提交的文件不切实际)变得太大)。

\ $ \ endgroup \ $

27 \ $ \ begingroup \ $如果使用编译器,输出源代码和输入源代码是否都必须小于512字节? \ $ \ endgroup \ $ – Trichoplax

\ $ \ begingroup \ $ @ LegionMammal978是的,它必须产生我指定的一种文件类型。但是,如果您认为找到了比解释语言更虚拟的虚拟机,请专门询问一下,我可能会允许它(这有点主观,所以我希望开始时非常严格,可以选择打开它)\ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $ @trichoplax我并没有意识到这一点,但是从一些阅读中看来,它是肯定的。编译为Python字节码绝对重要。因此对于python,输出大小将是所有pyc / pyo文件的总大小。我将通过这些基于注释的更新来尽快更新问题。 \ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $ @MartinRosenau-WGroleau已经问过类似的问题;它是编写挑战代码的标准,您可以使用挑战开始时已经存在的任何内容。 \ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $这将main函数定义为一个大型数组并初始化其第一个元素。这导致GCC将整个数组存储在生成的可执行文件中。

因为此数组大于2GB,所以我们需要向GCC提供-mcmodel = medium标志。根据规则,分数中包括了额外的15个字节。

我花了一些时间来测试@hvd的建议-并找到一台有足够果汁来处理它的机器。最终,我找到了一个旧的非生产型RedHat 5.6 VM,它具有10GB RAM,12GB交换空间和/ tmp设置为大型本地分区。 GCC版本是4.1.2。总编译时间约为27分钟。

由于CPU和RAM的负载,建议不要在任何与生产相关的远程机器上进行此编译。

\ $ \ endgroup \ $

32 \ $ \ begingroup \ $ @Sparr缺少值的元素将被初始化为0 \ $ \ endgroup \ $ –数字创伤

\ $ \ begingroup \ $我在这里反对我的解决方案,但是...您不需要。您可以只使用main [1<< 30] = {1}; \ $ \ endgroup \ $ –维普托

\ $ \ begingroup \ $天哪。这是邪恶的。 X冻结了几分钟试图编译该代码。我开始寻找另一台可能重新插入并杀死gcc进程的计算机,直到它最终恢复正常。顺便提一句。如果您想要的值大于1 << 30,那么7 << 28是一个选择。 \ $ \ endgroup \ $ –卡巴斯德

\ $ \ begingroup \ $如果其他人想知道为什么编译该文件:stackoverflow.com/questions/34764796/…\ $ \ endgroup \ $ – T. C.

\ $ \ begingroup \ $这个答案在滥用继承和类型参数来创建递归。要了解正在发生的事情,首先简化问题会更容易。考虑类别X< A>。 {类别Y:X< Y> {Y y; }},它会生成具有内部类Y的通用类X A。XA .Y继承了X Y,因此X A .Y也具有内部类Y,则内部类Y就是X。 ; A> .YY这样,它还具有一个内部类Y,而内部类Y具有一个内部类Y等。这意味着您可以无限使用范围解析(。),并且每次使用它时,编译器都必须推断出另一个层次。继承和类型参数化。

通过添加其他类型参数,可以进一步提高编译器在每个阶段要做的工作。

考虑以下情况:在类X A中,A = 1。 {类别Y:X< Y> {Y y;}}类型参数A具有X A.Y类型。在类X A中,X是A。 {类别Y:X< Y> {Y.Y y;}}类型参数A具有X X X A .Y> .Y的类型。在类X A中,X是A。 {类别Y:X< Y> {Y.Y.Y y;}}类型参数A的类型为X< X< X< A> .Y> .Y> .Y。在类X< A,B>中{类别Y:X< Y,Y> {Y y;}}类型参数A为X< A,B> .Y,B为X< A,B> .Y。在类X A中,X是A。 {类别Y:X< Y> {YY y;}}类型的参数A为X .Y,X .Y> .Y和B为X .Y,X .Y> .Y,X .Y,X :: n;

这是在模板中实现的Ackermann函数。我无法使用h = a 4,2> :: n进行编译;在我的小型(6GB)机器上运行,但我确实将h = a 3,14&用于26M输出文件。您可以调整常量以达到平台极限-请参阅链接的Wikipedia文章以获取指导。

需要GCC的-g标志(因为它实际上占用了所有空间的所有调试符号),并且模板深度大于默认值。我的编译行结束为

\ $ \ endgroup \ $

6 \ $ \ begingroup \ $我真的很喜欢这个,但是我不确定我可以接受.o输出,因为我确实说过ELF / .exe / etc。 (并将其完全编译可以将其全部优化!)。还是+1(并确认)\ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $更新:正如Ben Voigt在回答中指出的那样,Linux上的GCC确实将ELF文件生成为.o输出,并且我已经能够确认< 3,14>变体,所以是的-这是有效的。 \ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $我期望C ++模板会出现一些荒谬的事情。我没想到Ackermann函数。 \ $ \ endgroup \ $ - 标记

\ $ \ begingroup \ $斐波那契能否为您提供更小的代码和更好的输出大小控制? \ $ \ endgroup \ $ –威尔·尼斯

\ $ \ begingroup \ $但是我们想要更大的代码! Fibonacci的大小几乎与纯线性代码相同(但编译时间比线性代码长)。您肯定可以在每个类中使用大小为A + B的静态数组来玩乐,现在我想到了... \ $ \ endgroup \ $ – Toby Speight

17 \ $ \ begingroup \ $ 1<<<< 30对于C来说已经足够了。由于这是汇编程序,因此大小以字节为单位。 \ $ \ endgroup \ $ –维普托

\ $ \ begingroup \ $ @viraptor我的系统具有32GB的RAM,并且我尝试构建您的代码。因为设法移交给ld,但是ld失败了。甚至-mcmodel = medium似乎也没有帮助。 \ $ \ endgroup \ $ – Iwillnotexist Idonotexist

\ $ \ begingroup \ $尝试强​​制使用黄金链接器:gcc -fuse-ld = gold ...编译/链接... eek!以1:29(89秒)完成,大小为1,073,748,000字节。 \ $ \ endgroup \ $ – lornix

\ $ \ begingroup \ $我终于在调用gcc -o g g.s -mcmodel = large -Wl,-fuse-ld = gold的64位Ubuntu 15.10上组装了它。最终计数:4,294,975,320字节,对于-mcmodel = large -Wl,-fuse-ld = gold,程序长度增加了32个额外字节。值得指出的是标题不正确;源是29个字节(不添加额外的标志)。 \ $ \ endgroup \ $ – user45941

\ $ \ begingroup \ $通过将分配增加到1≤33,我得到了8,589,942,616字节的可执行文件。 \ $ \ endgroup \ $ – user45941

\\\ begingroup \ $这是我从2005年开始的C答案。如果您有16TB的RAM,则将产生16TB的二进制文件。

struct indblock {uint32_t blocks [4096];}; struct dindblock {struct indblock blocks [4096];}; struct tindblock {struct dindblock blocks [4096];}; struct inode {char data [52]; / *不费心重新输入细节* / struct indblock ind; struct dindblock dint; struct tindblock tind;};结构体inode bbtinode; int main(){}

\ $ \ endgroup \ $

18 \ $ \ begingroup \ $"如果您有16TB RAM(不会),将产生一个16TB二进制文件。 -我也没有16TB硬盘!我无法真正验证这一点,但是还是很酷的。 \ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $我偶然发现了这个,并且看着编译器在地址空间不足时翻倒了。 \ $ \ endgroup \ $ –约书亚

\ $ \ begingroup \ $请不要尝试打高尔夫球。打高尔夫球破坏了代码示例的意图,并且这样做没有任何得分优势。截至2005年,该代码已经GPL。\ $ \ endgroup \ $ –约书亚

\ $ \ begingroup \ $ @BenVoigt无论如何,在这里永远都不能编辑其他人的代码。如果有问题,请发表评论。相关元发布:meta.codegolf.stackexchange.com/questions/1615/…\ $ \ endgroup \ $ – user45941

\ $ \ begingroup \ $ @Joshua:检查减价差异。 Mego仅添加了突出显示提示。 \ $ \ endgroup \ $ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

\ $ \ begingroup \ $#定义A B + B + B + B + B + B + B + B + B + B + B#定义B C + C + C + C + C + C + C + C + C + C #定义C D + D + D + D + D + D + D + D + D + D#定义D E + E + E + E + E + E + E + E + E + E + E + E#定义E F + F + F + F + F + F + F + F + F + F + F#定义F x + x + x + x + x + x + x + x + x + xint main(void){int x,y = A; }

实验表明,每个级别的#defines(如预期的那样)会使输出大约大十倍。但是由于此示例花费了一个多小时的编译时间,所以我再也没有继续" G"。

\ $ \ endgroup \ $

6 \ $ \ begingroup \ $具体来说,它是原始的“ #Billion Laughs”的实现。 \ $ \ endgroup \ $ –mınxomaτ

\ $ \ begingroup \ $哇,这实际上在GCC 4.9和Clang中造成了段错误。您使用了哪个编译器? \ $ \ endgroup \ $ –戴夫

\ $ \ begingroup \ $ @Dave:奇怪。当我使用make进行编译时,它会编译,但是如果我键入与make完全相同的命令,则会崩溃。而且它似乎与环境变量无关。 \ $ \ endgroup \ $ –托马斯·帕德隆-麦卡锡

\ $ \ begingroup \ $ import javax.annotation.processing。*; @ SupportedAnnotationTypes(" java.lang.Override")公共类B扩展了AbstractProcessor {@Override公共布尔过程(java.util.Set a, RoundEnvironment r){if(a.size()> 0){try(java.io.Writer w = processingEnv.getFiler()。createSourceFile(" C")。openWriter()){w。为(int i = 0; i< 16380; ++ i){for(int j = 0; j< 65500; ++ j){w。写("类C {int"); for(int i = 0; i< 16380; ++ i){ write(" i");} w.write(i +&#34 ;; int");} w.write(" i;}");} catch(Exception e){}}返回true;}}

导入java.io.Writer;导入java.util.Set;导入javax.annotation.processing.RoundEnvironment;导入javax.annotation.processing.SupportedAnnotationTypes;导入javax.annotation.processing.SupportedSourceVersion;导入javax.lang.model.SourceVersion;导入javax.lang.model.element.TypeElement; @SupportedAnnotationTypes(" java.lang.Override")@ SupportedSourceVersion(SourceVersion.RELEASE_8)公共类B扩展AbstractProcessor {@覆盖公共布尔过程(Set&lt ;?扩展TypeElement>批注,RoundEnvironment roundEnv){if(annotations.size()> 0){试试(Writer writer = processingEnv.getFiler()。createSourceFile(" C&#

......