研究!rsc公司

关于编程的想法和链接,通过

RSS公司

一路向下压缩文件
发布于2010年3月18日,星期四。

斯蒂芬·霍金开始时间简史关于这个故事:

一位著名的科学家(有人说是伯特兰·罗素)曾就天文学做过一次公开演讲。他描述了地球是如何围绕太阳公转的,以及太阳是如何围绕着被称为我们星系的众多恒星的中心公转的。演讲结束时,教室后面的一位小老太太站起来说:“你告诉我们的都是废话。世界真的是一个由一只巨大的乌龟背上支撑的平板。”科学家笑得很好,然后回答说:“乌龟站在什么上面?”“你很聪明,年轻人,很聪明。”老太太说。“但这是一路下来的乌龟!”

今天的科学家们非常确信,宇宙实际上并不是一直向下的乌龟,但我们可以在其他情况下创造这种情况。例如,我们有视频监视器一直向下一路写下理论书,购物车一直开下去.

这里有一个计算机存储等价物:看看里面r.zip(右拉链).它是一路向下的zip文件:每个文件的名称下都包含另一个zip文件右/右拉链.(对于惯用Unix的粉丝,r.tar.gz公司一直向下压缩tar文件。)就像购物车的队列一样,它永远不会结束,因为它循环回到自身:zip文件包含自身!而且,组装一个自我生成的zip文件可能要花费更少的工作而不是把所有的购物车放在一起,至少如果你是那种会读这个博客的人。这篇文章解释了如何。

不过,在我们开始自制zip文件之前,我们需要在自产项目上绕道走一小段路。

自我复制程序

自产项目的想法可以追溯到20世纪60年代。我最喜欢的问题陈述是肯·汤普森(Ken Thompson)在1983年图灵奖(Turing Award)演讲中的一句话:

在大学里,在玩电子游戏之前,我们会通过摆姿势进行编程练习来娱乐自己。其中最受欢迎的是编写最短的自产程序。因为这是一个脱离现实的练习,所以常用的工具是FORTRAN。实际上,FORTRAN是首选语言,原因与三种种族受欢迎的原因相同。

更准确地说,问题是要编写一个源程序,当编译和执行时,它将生成源的精确副本作为输出。如果你从未这样做过,我建议你自己尝试一下。如何做到这一点的发现是一个启示,它远远超过了被告知如何做到的任何益处。关于“最短”的部分只是一种激励,以展示技能并决定胜利者。

扰流板警报!我同意:如果你从未这样做过,我敦促你自己尝试一下。互联网使查找信息变得如此容易,令人耳目一新偶尔自己发现一些东西。继续,花几天时间来解决这个问题。此博客仍将在此处当你回来的时候。(如果你不介意剧透图灵奖颁奖辞值得一读。)



(扰流板堵塞器。)

http://www.robertwechsler.com/projects.html

让我们尝试编写一个Python程序来打印自身。它可能是一个打印声明,所以这是第一次尝试,在解释器提示下运行:

>>>打印'你好'你好

这不太管用。但现在我们知道了程序是什么,所以让我们打印出来:

>>>打印“打印“hello”"打印“hello”

这也不太管用。问题是,当您执行一个简单的print语句,它只打印自身的一部分:print的参数。我们还需要一种方法来打印程序的其余部分。

诀窍是使用递归:编写一个字符串,它就是整个程序,但它本身不见了,然后你在把它传给打印之前把它插进去。

>>>s='打印%s'; 打印s%repr打印“打印%s”

不完全是,但更接近:问题是字符串实际上不是程序。但现在我们知道了该计划的一般形式:s='%秒'; 打印s%repr.这就是要使用的字符串。

>>>s='s=%s;打印s%%repr'; 打印s%reprs='s=%s;打印s%%repr’;打印s%repr

为胜利而递归。

这种形式的自产项目通常称为奎因,为了纪念哲学家和逻辑学家W.V.O.奎因,谁发现了这个自相矛盾的句子:

“前面加上引语会产生谬误”
在引用之前会产生错误。

自制奎因最简单的英语形式是命令,如:

打印此内容,然后打印其报价:
打印此内容,然后打印其报价:

Python没有什么特别的地方可以让奎宁成为可能。我所知道的最优雅的奎因是一个Scheme程序,它是该程序的直接翻译,尽管有些难以理解情绪:

(λ(x)`(,x个',x个))'(λ(x)`(,x',x)))

我认为Go版本是一个更清晰的翻译,至少就引用而言:

/*去奎因*/成套设备总管导入“柔性制造技术"函数main(){fmt公司。打印(“%s%c%s%c\n“,q,0x60,q,x60)}var q=`/*去奎因*/成套设备总管导入“fmt”函数main(){fmt公司。打印(“%s%c%s%c\n”,q,0x60,q,x60)}变量q=`

(我将数据文字全部涂成了绿色,以明确什么是程序,什么是数据。)

Go程序有一个有趣的特性,即忽略讨厌的换行符最后,整个程序是同一个东西的两倍(/*去奎因*/。。。q=`).这让我思考:也许可以写一个自我复制的程序只使用重复运算符。你知道什么编程语言本质上只有一个重复操作符吗?用于编码Lempel-Ziv压缩文件的语言就像使用的那些gzip公司拉链.

自我复制Lempel-Ziv程序

Lempel-Ziv压缩数据是一个包含两个基本指令的指令流操作码:文字(n个)然后n个字节的数据意味着写入n个字节到解压缩输出,重复(d日, n个)意味着向后看d日当前位置的字节数并复制n个你在那里找到的字节数到输出流中。

那么,编程练习是:编写Lempel-Ziv程序只使用运行时自动打印的两个操作码。换句话说,编写一个解压缩到自身的压缩数据流。您可以随意为字面意义的重复操作码。要获得大奖,请找到一个减压到由任意前缀和后缀包围,这样序列就可以嵌入到实际的gzip公司拉链文件,该文件具有固定格式的标头和尾部。

扰流板警报!我敦促你在继续阅读之前自己尝试一下。这是度过一个懒散下午的好方法我没有的一个关键优势是:你知道有解决方案。



(扰流板堵塞器。)

http://www.robertwechsler.com/thebest.html

顺便说一下,这是相对湿度、gzip文件。

$gunzip<r.gz>r$cmp r r.gz$

关于相对湿度就是那些坏了的浏览器吗通常先解压缩下载的gzip数据,然后再将其存储到磁盘将正确处理此文件!

足够的拖延时间来隐藏破坏者。让我们用这个简写来描述Lempel-Ziv指令:L(左)n个R(右)n个缩写文字(n个)重复(n个, n个),程序假设每个代码都是一个字节。L0级因此是Lempel-Ziv no-op;L5级 你好打印你好;也是如此L3级 帮助 R1级 第一层 .

这是一个Lempel-Ziv程序,它可以自动打印。(每行是一条指令。)


代码输出
无操作L0级
无操作L0级
无操作L0级
打印4个字节L4级L0 L0 L0L4L0 L0 L0L4
重复最后4个打印字节R4级L0 L0 L0L4
打印4个字节L4级R4 L4 R4 L四R4 L4 R4 L四
重复最后4个打印字节R4级R4 L4 R4 L四
打印4个字节L4级L0 L0 L0-L0L0 L0 L0-L0

(两列“代码”和“输出”包含相同的字节序列。)

这个程序有趣的核心是6字节序列L4 R4 L4 R4 L4 R4,它打印8字节序列R4 L4 R4 L4R4 L4-L4 R4-L4.也就是说,它在前后打印一个额外的字节。

当我们试图编写自产Python程序时,基本问题是print语句总是较长比它打印的要多。我们用递归解决了这个问题,通过将字符串插入自身来计算要打印的字符串。这里我们采取了不同的方法。Lempel-Ziv计划是特别是重复的,因此重复的子串结束包含整个片段。递归位于表示程序而不是其执行。不管怎样,这个片段都是关键点。决赛前R4级,输出滞后于输入。一旦执行,输出就是前面的一个代码。

这个L0级no-op已插入程序的一个更通用的变体,可以自我复制添加任意的三字节前缀和后缀:


代码输出
打印4个字节L4级aa bb抄送L4级aa bb抄送L4级
重复最后4个打印字节R4级aa bb抄送L4级
打印4个字节L4级R4 L4 R4 L四R4 L4 R4 L四
重复最后4个打印字节R4级R4 L4 R4 L四
打印4个字节L4级R4级xx-yy-zz年xx月xx日R4级xx-yy-zz年xx月xx日
重复最后4个打印字节R4级R4级xx-yy-zz年xx月xx日

(输出列中的字节序列为aa bb抄送,然后“代码”列中的字节序列,然后xx-yy-zz年xx月xx日.)

我花了一个安静的星期天的大部分时间才走到这一步,但当我来到这里的时候,我知道比赛已经结束了我赢了。从所有这些实验中,我知道它很容易创建打印自己的程序片段减去一些指令甚至打印任意前缀的然后是它本身,减去一些指令。额外的aa bb抄送在输出中提供了附加此类程序片段的位置。类似地,很容易创建要附加的片段xx-yy-zz年xx月xx日它自己打印,减去前三条指令,再加上一个任意后缀。我们可以使用该通用性来附加适当的收割台和拖车。

这是最后一个程序,它打印自己周围的任意前缀和后缀。【P】表示第页-前缀的字节压缩形式P(P);类似地,【S】表示-后缀的字节压缩形式.


代码输出
打印前缀 【P】 P(P)
打印第页+1个字节 L(左)第页+1 [P] L(左)第页+1 [P] L(左)第页+1
重复最后一次第页+1个打印字节 R(右)第页+1 [P] L(左)第页+1
打印1字节 第一层R(右)第页+1 R(右)第页+1
打印1字节 第一层第一层 第一层
打印4个字节 L4级R(右)第页+1L1 L1 L4层 R(右)第页+1L1 L1 L4
重复最后4个打印字节 R4级 R(右)第页+1L1 L1 L4层
打印4个字节 L4级R4 L4 R4 L四 R4 L4 R4 L四
重复最后4个打印字节 R4级 R4 L4 R4 L四
打印4个字节 L4级R4 L0 L0升+1 R4 L0 L0升+1
重复最后4个打印字节 R4级 R4 L0 L0升+1
无操作 L0级
无操作 L0级
打印+1个字节 L(左)+1 R(右)+1【S】 R(右)+1【S】
重复最后一次+1个字节 R(右)+1 R(右)+1【S】
打印后缀 【S】

(输出列中的字节序列为P(P),然后“代码”列中的字节序列,然后.)

自我复制zip文件

现在橡胶遇到了路面。我们已经解决了实现自主生产的主要理论障碍zip文件,但存在一些实际障碍仍然在我们的路上。

第一个障碍是翻译我们自己制作的Lempel-Ziv程序,用简化的操作码编写成真正的操作码编码。RFC 1951年描述了gzip和zip中使用的DEFLATE格式:一系列块,每个块是使用哈夫曼码编码的操作码序列。哈夫曼码分配不同长度的位字符串到不同的操作码,打破了我们上面的假设,即操作码具有固定长度。但是等等!我们可以小心地找到一组固定大小的编码这说明了我们需要表达的内容。

在DEFLATE中,有文字块和操作码块。文本块开头的标头是5个字节:

如果我们的翻译L(左)上面的操作码每个为5个字节R(右)操作码每个字节必须为5个字节,包含所有字节计数以上按5倍缩放。(例如,L4级现在有一个20字节的参数,R4级重复最后20个字节的输出。)操作码块用一个重复(20,20)指令远远不够5字节:

幸运的是,一个操作码块包含两个重复(20,10)指令具有相同的效果,正好是5个字节:

对其他大小的重复进行编码(R(右)第页+1R(右)+1)需要更多的努力还有一些卑鄙的伎俩,但事实证明我们可以设计重复任意数量的5字节代码从9字节到64字节。例如,以下是10字节和40字节的重复块:


10字节的重复块太短了两位,但是每个重复块后面跟着一个文字块,从三个零位开始,然后填充到下一个字节边界。如果重复块的结尾短于一个字节的两位但后面是一个文本块,文本块的padding将插入额外的两位。类似地,40字节的重复块过长5位,但它们都是零位的。启动文字块太晚了五位从垫子上偷走碎片。这两个技巧都有效,因为任何重复块为零,第一个字节中的位为任何文字块的也为零,所以边界不是直接可见的。如果文本块以一位开头,这个卑鄙的伎俩行不通。

第二个障碍是zip存档(和gzip文件)记录未压缩数据的CRC32校验和。由于未压缩的数据是zip档案,正在校验的数据包括校验和本身。所以我们需要找到一个值x个这样的写作x个进入之内校验和字段使文件校验和为x个.递归反击。

CRC32校验和计算将整个文件解释为一个大数字并进行计算将该数字除以特定常数时的余数使用特定的除法。我们可以努力建立适当的方程和求解x个.但坦率地说,我们已经解决了一个令人讨厌的递归难题今天,和够了就够了.只有40亿种可能性x个:我们可以编写一个程序,依次尝试每个程序,直到找到一个有效的。

如果您想自己重新创建这些文件,有一个还有几个小障碍,比如确保tar文件是多个512字节,并将相当大的zip拖车压缩为最多59个字节,因此R(右)+1至多R(右)64.但它们只是一个简单的编程问题。

所以你有了它:相对湿度(gzip文件一直向下),r.tar.gz公司(一直向下压缩tar文件),r.zip(右拉链)(一直向下压缩文件)。我很遗憾我找不到任何程序坚持无限递归解压缩这些文件。看着它们蠕动会很有趣,但是它看起来没有那么复杂拉链炸弹破坏了乐趣。

如果你感到特别有野心,以下是rgzip.go网址,这个去吧生成这些文件的程序。我想知道您是否可以创建一个包含gzipped tar文件的zip文件包含原始zip文件。Ken Thompson建议尝试制作一个zip文件递归地包含一个稍大的自身副本,因此,当您深入zip文件链时每个都会变大一点。(如果您确实处理了其中任何一项,请留下评论。)


附言:如果不分享我最喜欢的自制程序:单行shell脚本,我无法结束帖子#!/箱子/猫.

(评论最初通过Blogger发布。)

  • 塔夫斯 (2010年3月18日上午9:46)在Mac OS X上的Safari中,设置了“下载后打开“安全”文件”选项(默认为打开),它会不断解压缩和填充我的磁盘。“安全”的确…

  • 亚伦·戴维斯 (2010年3月18日下午1:59)> #!/箱子/猫

    很不错的。我有点偏爱“十大清单”,我自己。。。。

  • 沙姆斯 (2010年3月18日下午3:46)这有点作弊,但在Python中,您可以编写任意的自重复程序,非常简单(如果您也假设使用标准库):

    进口检查系统
    打印inspect.getsource(系统模块['__main__']),

  • 伊桑(EthanG) (2010年3月18日下午4:39)@tafs:至少它会响应下载窗口中的取消按钮。在我杀死它之前,我的垃圾箱里有了r-962(963个解包),总共有3.8MB的垃圾。

  • 尼克 (2010年3月18日下午6:23) 此帖子已被作者删除。

  • 尼克 (2010年3月18日下午6:25)也许r.zip可以包含自身的副本。。。

    让我想起了“我不能在X号录音机上播放”。。。

  • 卢克 (2010年3月19日上午7:18)C对字符串的处理使它有点烦人,但并不过于复杂。。。我想知道是否有人能想出更短的(但仍然是裸C)。

    char qs[160];char*q(char*s){char*rs=qs;do{if(*s==0x22)*(rs++)=0x5C;*(rs++)=*s;}while(*(s++));返回qs;}int main(){char*s=“char qs[160];char*q(char*s){char*rs=qs;do{if(*s==0x22)*(rs++)=0x5C;*(rs++)=*s;}while(*(s++));return qs;}int main;打印f(s,q(s));}

  • 卢克 (2010年3月19日上午7:21)尽管有一些与字符串处理相关的注释,但C版本相对较短(最接近我编写的IOCCC候选者;):

    char qs[160];char*q(char*s){char*rs=qs;do{if(*s==0x22)*(rs++)=0x5C;*(rs++)=*s;}while(*(s++));返回qs;}int main(){char*s=“char qs[160];char*q(char*s){char*rs=qs;do{if(*s==0x22)*(rs++)=0x5C;*(rs++)=*s;}while(*(s++));return qs;}int main;打印f(s,q(s));}

  • 卢克 (2010年3月19日上午7:22)很抱歉,我的浏览器在第一次尝试时返回404。。。

  • 蛛形纲 (2010年3月19日上午9:19)考虑到crc32问题,您有什么建议可以告诉您如何编写一个版本,将其解压缩为一个更大的版本吗?

  • 俄罗斯考克斯 (2010年3月19日上午10:08)@蜘蛛侠:我想你可以设计一个序列,当插入到一个特定的位置时(无论多少次),它都不会影响crc。但我还没有做数学题。

  • 尼克约翰逊 (2010年3月19日上午10:13)不久之后,我就想到了这一点。原则上,这不难,因为CRC只纠正小错误。如果序列是一组自身打印两次的指令,那么您将被排序!

  • 阿贾尚卡尔 (2010年3月22日下午12:40)迷人的帖子!

    有可能创建一个不使用L0 no-ops的纯LZ奎因(没有页眉或页脚)吗?

  • 阿贾尚卡语 (2010年3月23日上午10:39)根据记录,答案是肯定的,可以用这个16位操作码的奎因来完成(你最容易解释的解决方案是20位):

    二级缓存二级缓存
    二级缓存二级缓存
    二级缓存二级缓存
    R4,3
    L4 R4,3 L4 R4.3 L4
    4.3兰特

    我找到的最短的是14个操作码:
    L0级
    L4 L0 L4 L0L4
    L0级
    4.3兰特
    L4 R4,3 L4 R4.3 L4
    4.3兰特

  • 俄罗斯考克斯 (2010年3月23日12:05 PM)整洁。如果你从上面的核心模式开始,你可以在两端插入L1L1L1L1,而不是L0L0L0,但这甚至更长。

    第一条注释中的链接可以归结为这条9指令。它利用了这样一个事实,即你可以有一个比备份更长的重复长度

    L0级
    L2 L0 L2级
    L0级
    2.3兰特
    L2 R2,3 L2级
    2,3

    (R2,3==返回2个字节并复制3:如果当前输出以xy结尾,则附加xyx。)

  • 阿贾尚卡尔 (2010年3月23日12:20 PM)该死,真是鬼鬼祟祟。我喜欢它。在我对试图找到一个纯3,2的解决方案感到沮丧之后,我偶然采用了4,3的方法。但我从未想过要做2、3。

  • 米西 (2010年3月24日下午2:56)关于CRC:您可以修改您的程序,使其在某处包含任意的4字节序列(只需一次)。通过修改这4个字节,可以使CRC成为任意值。
    因此,您首先选择了CRC(例如为0x00000000),创建了自己制作的存档,最后选择了4个字节,这样CRC就是您想要的。因此,完全避免了递归问题。

  • k5用户 (2010年3月25日上午11:54)游戏已经很晚了,但递归zip已经存在很长时间了。反病毒世界已经知道它们至少8年了。有人可能会对AV产品发起拒绝服务攻击,该产品设置为通过发送死亡zip来扫描压缩文件。为了解决这个问题,许多AV程序在文件中设置了一些可配置的“深度”后停止处理。

  • 米西 (2010年3月27日上午9:12)所以,我说的是:
    记录_固定.gz

    它是一个gzip奎因,其中字节102-105是“定点”。也就是说,您可以将它们更改为您想要的任何内容,文件仍将解压缩到自身。(当然,如果您更改了它们,CRC将不会检出。)

    因此,我创建了这个文件,将gzip页脚中的CRC设置为全部0,然后“反向计算”这四个字节中的CRC,因此整个文件的CRC实际上为0。我相信,基于这个想法,可以创建一个中间有一个部分的文件,它可以在压缩时复制自己,而CRC保持不变。我写完后会把它贴在这里。

    您可能还需要查看此文件的内部,因为它基于与您的想法略有不同的想法。例如,我不依赖于“repeat”操作码为5个字节。有一个“源代码”可能稍微容易阅读:记录_固定.lgz

  • 米西 (2010年3月27日下午3:47)这里是:记录导出.gz.
    它有一个32字节的块,在解压缩时重复,CRC总是正确的(和0)。

    不幸的是,gzip页脚还包含大小字段,这当然是不正确的。。。直到解压缩文件27次。:)此时,复制块的大小将变为4GB,32位大小字段被设置为余数。(但我没有检查。:)

    考虑到这一点,我意识到有一种更简单(但有点作弊)的方法可以创建“成长的gzip quine”。您只需复制整个文件。由于gzip只是将连接的输入的输出连接起来,因此它可以在不太注意大小或crc字段的情况下工作。因此,这里有一个文件,其gunzipping与将其与自身连接是一样的:记录_上传.gz

    (“源”位于同一目录中。)

  • 马克·鲁夫 (2010年5月1日凌晨1:57)你好,

    非常有趣的研究和很棒的写作!继续努力。

    当做,

    马克

  • 用户未知 (2010年5月1日下午3:23)这是我不太熟悉的奎因:
    导入java.math。大整数;
    /**
    (c) Stefan Wagner,GPLv3.0
    */
    奎因级
    {
    公共静态void main(String[]参数)
    {
    BigInteger b=新的BigIntiger("3125672623196693767569686149189009633452 2377871159551965921417137170609691214223 9208376749605139774443708326203800130556 5247549291738666720120851102563432688661 2425053632619026133552590824825360959495 9103568388341399920152904163137391991148 8600579488934249116624219425362354637760 9935667840623358056717110027295132562103 9400252768836739128617742678124740473856 7878670179316536315099060433926849016933 4865116792986969613917692005305319947405 7778267800604078704652663104779321903695 4971735707525104532138973326414147694788 6144049586837524382107377428450195285880 0467794888319592557310425481240448120408 1531669064199685228190893676717975716990 4846241527401973665847012561439332697517 5470668411522967977332908759408086343490 26570");
    整数i=0;
    for(字节c:b.toByteArray())
    {
    ++i;
    如果(i==159)
    系统输出打印(b);
    System.out.print((char)c);
    }
    }
    }
    这里是我最短的bash-quine:。是的,确实如此。也许你没有看到它——以下是你制作它的方法:

    触摸_;chmod a+x _/_

  • 斯特芬茨 (2010年5月2日上午10:02)在Perl中(一行没有换行符):

    $q=chr(39)$s='$q=chr(39)$s=%s%s%s;打印f$s,$q,$s,$q;';打印f$s,$q,$s,$q;

  • 斯特芬茨 (2010年5月3日凌晨3:18)C版本也一样(一行没有换行符):

    main(){char q=34;char*s=“main(;打印f(s,q,s,q);}

  • 达格温 (2010年5月19日4:31 AM)Hioefukky任何在固定深度后停止的防病毒程序都会将该文件标记为恶意软件,而不是将其视为良性的。主要原因是黑客显然只会将恶意软件隐藏在比阈值深一层的嵌套ZIP文件中。

  • 邓肯 (2010年5月25日上午5:52)“我很遗憾,我找不到任何坚持无限次递归解压缩这些文件的程序。看着它们蠕动会很有趣,但看起来不那么复杂的拉链炸弹破坏了乐趣。”

    恐怕我发现了炸弹。我觉得这很有趣,所以上周我给几个同事发了一封r.zip的电子邮件。今天邮件服务器崩溃了。

    我们的电子邮件是Lotus Notes,McAfee是病毒扫描程序。看起来,虽然桌面版的McAfee在解压缩时只扫描zip文件,但服务器版本会检查每一封电子邮件的zip文件。。。

    似乎花了一周的时间来填充光盘。

  • 弗兰兹 (2010年11月4日上午5:25)一直以来的计算机科学家

    漂亮的帖子,谢谢!
    但我发现购物车的比喻很容易误导人。钥匙
    对于奎因来说,就是拥有包含
    自身的表示(要打印的字符串)。最后,行动
    表示表示(执行“打印”指令)
    使表示真实(一个新程序,与它的
    父级)。大车圈中没有大车的表示。

    其他艺术背景有制作奎因的潜力,因为它们
    模糊了现实与其表现之间的界限。我在想
    关于埃舍尔的一些绘画,皮兰德罗的“六个角色
    寻找作者”,或艾伦的《开罗的紫玫瑰》。

    然而,它们都不是奎因,因为艺术作品不是
    代表自己(例如,“开罗紫玫瑰”的代表是
    关于埃及的电影,而不是大萧条的故事)。

    更接近真正奎因的例子(可能是偶然的)是
    “13楼”。(前扰流板)

    在电影中,洛杉矶的一组计算机科学家创建了一个
    模拟洛杉矶,却发现他们就是自己
    洛杉矶团队进行的计算机模拟的一部分
    科学家。愚蠢的作者在三个层面上停止了这部电影(在
    洛杉矶最深处的年份是1937年,没有
    计算机)。但只要等待足够的(cpu)时间。。。这将是
    一路走来的计算机科学家!

  • 亚伦·戴维斯 (2010年11月4日上午5:36)eXistenZ公司当然现在开端.在书中,有树叶屋还有鲍杰斯和纳巴科夫的各种作品。

  • AndyMm公司 (2010年11月29日下午2:00)在Javascript中使用整数。

    c=[59,21,51,,,53,19,62,71,74,0,57,21,58,21,51,53,19.57,20,14,13,19,57,3,15,38,21,57,54,11,23,
    43,76,74,65,70,63,6,62,74,71,69,27,64,57,74,27,71,60,61,0,59,51,3,57,53,3,12,8,1,18,59,19];
    对于(a=b=[];a<65;a++)b+=a^3?字符串.fromCharCode(c[+a]+40):c;

    使用RegExp。看到人们以更疯狂的方式使用RegExp,但这里有一个简单的方法。

    unescape(q=/unescape%28q=%2FQ%2F%5B-1%5D%29.替换%28%2FQ%2F,q%29/[-1]).替换(/q/,q)

  • 莱茵托 (2011年1月7日下午1:50)《13楼》是丹尼尔·加卢耶(Daniel Galouye)的一本书《Simulacron 3》的电影版。http://en.wikipedia.org/wiki/Simulacron-3
    法斯宾德也拍了一部电影。

  • 卡科伊 (2011年3月15日凌晨2:47)我正在尝试编译您的代码,以便修改它以获得与此类似的结果http://www.steike.com/code/useless/zip-file-quine网站/,但我遇到了以下错误:

    rgzip.go:347:未定义:字节。添加
    rgzip.go:700:panic:panic的参数太多(“无法编码REP”,n)
    rgzip.go:710:未定义:扁平。新放气阀
    rgzip.go:1057:不能在函数参数中使用&f.codebits(type*[19]int)作为type[]int

    作为新手,你能给我指出正确的方向吗?

  • 匿名(2011年4月7日上午6:49)@卡科伊:
    字节。添加已从语言中删除。更改为附加
    panic将文字解释为两个参数。删除“,n”
    扁平。NewDeflater不再存在。改为平板电脑。NewWriter(新作者)
    codebits[numCodes]int让程序疯狂。更改为codebits[]int

    现在编译。不知道它是否有效。

  • 匿名(2011年4月7日上午6:59)@卡科伊:
    字节。添加已从语言中删除。更改为附加
    panic将文字解释为两个参数。删除“,n”
    扁平。NewDeflater不再存在。更改为扁平。NewWriter(新作者)
    codebits[numCodes]int让程序疯狂。更改为codebits[]int

    现在编译。不知道它是否有效。

  • 匿名(2011年6月10日下午7:39)我采纳了你的建议,并尝试自己创建一个。我用php进行了尝试,结果发现它微不足道。

    简单地说:

    会做到的。

    但我想你是想表达不同的观点。

  • 匿名(2011年6月10日下午7:40)我采纳了你的建议,并尝试自己创建一个。我用php尝试了一下,结果发现它很简单。

    简单地说:
    <? php(电话)

    打印(文件获取内容(__file_));
    ?>
    会做到的。

    但我想你是想表达不同的观点。

  • 沈浩浪 (2011年7月17日上午9:48)Unix外壳:
    z=\'a='z=\$z a=$z$a$z \;eval echo\$a';评估echo$a

  • 科迪(2011年11月21日上午5:52)前几天我写了这篇文章。至于C版本,其中一些版本存在不符合C标准的问题(例如,main的返回类型没有int)。另一个例子是printf的隐式声明(no#include<stdio.h>)

    所以我也修复了这个问题(希望它能粘贴好):

    #包括<stdio.h>
    int main(){char*p=“#include<stdio.h>%cint main(”{char*p=%c%s%c;printf(p,10,34,p,34,10,10);返回0;%c}%c“;打印(p,10,34,p,34,10,10);返回0;
    }

    wc在该源文件上运行,其价值是:

    3 16 173奎因
    (对于windows用户,这意味着:3行,16个单词,173个字符)

    至于在php中尝试并直接包含该文件的人,事实上这一点非常不同。那是作弊,不是奎因。如果您通过在源代码中读取文件来包含该文件,那么(正如您所指出的)这几乎不是一个挑战。

    对于这篇文章的作者来说,谢谢你——很有趣。(我是通过查找zip文件格式找到它的,因为我现在记不得了;我认为是从wiki中引用的吗?)

  • 科迪(2011年11月21日上午6:04)还有一件事我忘了回答。

    关于抗病毒和递归zip文件:至少从我所看到的来看,它通常是一个用户定义的变量。它不是硬编码的。所以它并没有真正的缺陷。事实上,有些事情在第一眼就很难判断是否正常(有些av可能会报告正常,而其他av则可能报告不正常,以此类推)。即使是反贿赂技巧也能让防病毒检测引擎在不考虑恶意软件的情况下认为它是恶意软件。当然,更“可怕”的把戏是背驮——在av引擎扫描文件时,恶意软件会感染文件/其他任何东西。

    尽管如此,在安全性方面,假阳性和假阴性一样糟糕(另一个类似的事情——配置糟糕的防火墙可能真的很糟糕)。事情就是这样发展的,有时我们都要好好利用。当然,如果一个文件被压缩多次,可能会引起怀疑,也许应该这样做。他们必须隐藏什么?因此,归根结底,这是一个运用常识、理解事物如何工作的问题,如果所有病毒协同工作,抗病毒也会发挥相当好的作用。

  • 大卫·瓦格纳 (2012年1月28日10:10 PM)这太棒了!谢谢你发布这个谜题。

    我很高兴看到简化版,其中只允许使用Ln个和Rn个操作码(Rn、 米不允许)。我很好奇最短的奎因是什么。

    为了好玩,我决定扔一个SAT解算器。以下是我的发现。最短的奎因是16字节长:
    L0 L0 L0-L2 L0-L0-L2-L0-L2-R3-R2 L2-R3-R3-R2
    或者,以解析形式:
    L0级
    L0级
    10个
    L2 L0 L0级
    L2 L0 L2级
    R3级
    R2级
    L2 R3 R2级
    R3级
    R2级

    假设我的SAT代码是正确的,就没有短的奎因了。也没有长度为17的奎因。然而,似乎有更大长度的奎因。

    如果你好奇我是如何将其编码为SAT的,这是我用来搜索五分长度的方法n个:

    我定义了一个n个-未知字节数组,调用它In,所以In()是输入的第个字节。(我们将添加约束以强制它也成为输出的第个字节。)

    然后,我定义了一个(n个+1) x个(n个+1) 布尔未知值数组,active(.,.),其中

    活动(,j个)如果In(0。。-1) 是一个解析良好的字节序列(即,它不会在未完成的字符串文字中间结束),并解压缩in(0。。-1) 产生输出In(0。。j个-1).

    写下一组约束并不太难,这些约束根据in(.)的条目定义active(.,.)的条目的条目。然后我发出约束以要求active(0,0)为true,并要求该active(n个,n个)是真的。然后我调用SAT解算器来找到一个考虑所有这些约束的解决方案。

    这很有趣!谢谢你分享这个谜题。