2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								layout: post
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								title: 关于ZIP Quine与自产生程序的探索
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								tags: [压缩包, Quine, 自产生程序, Quine Relay]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  描述自己的代码……是一种什么样的感觉?<!-- more -->    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 起因
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  前段时间我在折腾[博客部署 ](/2025/08/10/tilde.html#%E4%BD%BF%E7%94%A8git-hooks%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E5%8D%9A%E5%AE%A2 )的时候,回顾起了好久以前写的[部署脚本 ](/deploy.sh )。对于全站打包的这个步骤,本来我打算利用这个压缩包结合[Service Worker做离线浏览 ](/2025/08/01/sw-proxy.html ),但因为没有合适的方案所以放弃了。而现在对于这个压缩包,我又有了一个特别的想法。事实上在这个下载全站的压缩包中,里面的内容和实际的网站并不完全相同,因为在这个压缩包里缺少了压缩包本身。所以把这个压缩包解压之后直接当作网站打开,会发现下载压缩包的链接是无效的,除非在解压之后把压缩包移动到网站里才行……   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  于是我就在想有没有一种可能可以让压缩包解压之后里面又包含了这个压缩包本身?似乎是个不太可能的事情,但我以前听过类似的东西,也许并非不可能?所以这次就来探索一下吧。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 自包含压缩包的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  在很久之前, ( ) , droste.zip ](https://alf.nu/s/droste.zip ), 在2005年制作 ](https://web.archive.org/web/20090106171423/http://tykje.com/code/useless/zip-file-quine )出来的。当时我只知道它很神奇,原理什么的并不清楚,另外在网上也基本上找不到类似的压缩包。现在再回看时发现[介绍 ](https://alf.nu/ZipQuine )里包含了一些相关的链接,甚至还有一篇能自己制作类似压缩包的论文,所以接下来就可以看一下这些链接来理解这种压缩包是如何制作的了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  关于原理方面,先看[Will Greenberg ](https://github.com/wgreenberg )制作的一个[示例 ](https://wgreenberg.github.io/quine.zip/ ), , ( ) ( , ) , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  这个问题看起来还挺复杂,不过在仓库的[Issues ](https://github.com/wgreenberg/quine.zip/issues/1 )就有人给出了几种解法(当然,这个题目解法不唯一),所以在理论上应该是可行的,那么接下来就需要研究压缩文件的格式来实现它了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 实现ZIP Quine的探索
  
						 
					
						
							
								
									
										
										
										
											2025-09-17 12:55:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  在[Russ Cox ](https://swtch.com/~rsc/ )写的《[Zip Files All The Way Down ](https://research.swtch.com/zip )》文章中, , , , , , , , : 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 2 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 2 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 2 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 1
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 4 4
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 2 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								repeat 2 2
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								print 0
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  我们把这些指令粘贴到[quine.zip ](https://wgreenberg.github.io/quine.zip/ )这个谜题中, , : rgzip.go ](http://swtch.com/rgzip.go ),只是代码里面到处都是用来构建压缩包的十六进制数字,完全看不懂😂。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  另外这个方案是针对使用基于LZ77与哈夫曼编码的DEFLATE压缩算法, , , ( ) , , , Matthew Barber ](https://github.com/honno )写了一篇很棒的[文章 ](https://github.com/honno/gzip-quine ), , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  还有一点, ? , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  这么来看既然TGZ可以, ? , , , `repeat 64 64` 这样的指令能够满足要求, , , , , , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 12:55:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  虽然Russ Cox写的文章看起来做不到包含更多内容了, , , Ruben Van Mello ](https://github.com/ruvmello )写了一篇论文《[A Generator for Recursive Zip Files ](https://www.mdpi.com/2076-3417/14/21/9797 )》,在这篇论文里他不仅解决了包含的额外数据过少的问题,还编写了一个通用工具,能让普通人也能生成这样的压缩包,而且他还创新性的做了一种像衔尾蛇一样的双层嵌套循环压缩包,非常的有意思,所以接下来我打算试试他的方案。   
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  在这篇论文中, , , , , , ( ) , , ( ) , , , ? , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 制作一个嵌套循环的ZIP Quine
  
						 
					
						
							
								
									
										
										
										
											2025-09-17 12:55:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  在实现了常规的ZIP Quine之后, ( ) , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  另外既然这里面有两个压缩包, , , ( ) , , , ( ) ? , ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  现在所有的理论都足够了, , Mabbs ](https://github.com/Mabbs/Mabbs.Project )吧, , ? , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  接下来就该使用论文中提到的生成工具:[zip-quine-generator ](https://github.com/ruvmello/zip-quine-generator ), , , `--loop` ”参数就可以用这个程序创建嵌套循环的ZIP Quine了。不过它原本的代码不能修改里面生成的压缩包的名字, 压缩后的文件属性是隐藏文件 ](https://github.com/ruvmello/zip-quine-generator/blob/3b8cf977e7a93bb956ad966d5e3b4d503f410529/src/main/kotlin/zip/ZIPArchiver.kt#L845 ),还有[生成的压缩包中文件的创建时间总是当前时间 ](https://github.com/ruvmello/zip-quine-generator/blob/3b8cf977e7a93bb956ad966d5e3b4d503f410529/src/main/kotlin/zip/ZIPArchiver.kt#L29 ),以及[给文件内填充额外数据的代码里面填的是作者的声明 ](https://github.com/ruvmello/zip-quine-generator/blob/3b8cf977e7a93bb956ad966d5e3b4d503f410529/src/main/kotlin/zip/ZIPArchiver.kt#L30 ), , , , , `kotlinc src/main/kotlin -include-runtime -d output.jar` 就可以了, , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  最终我给我的[Mabbs ](https://github.com/Mabbs/Mabbs.Project )项目创建了[Infinite Mabbs ](https://github.com/Mabbs/Mabbs.Project/releases/tag/Final-version )这个发布,生成的文件也可以在[这里 ](/assets/Mabbs.zip )下载,这也算是不枉我研究半天这个论文了😆。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 自产生程序的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  说起来自包含压缩包为什么叫做ZIP Quine? ? , , , , 维基百科 ](https://en.wikipedia.org/wiki/Quine_(computing )#Name )的说明。现在提到Quine一般代表的就是自产生程序, , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 实现Quine的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  那么什么是自产生程序?简单来说就是程序的源代码和程序的输出完全相同的程序,而且通常来说不允许通过读取/输入源代码的方式实现。按照一般的想法, , , , , , , , : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```python
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								c = 'c = %r; print(c %% c)'; print(c % c)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  这里的变量中就以数据的形式存储了程序的代码,而在输出的时候除了变量内的代码,又通过引用的方式又把变量的内容放回到赋值的地方,所以它的输出就和原本的代码一样了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  其实Quine的实现思路都差不多是这样, Rosetta Code ](https://rosettacode.org/ )中找到[各种语言实现的Quine ](https://rosettacode.org/wiki/Quine ), , , , , 这里 ](https://esolangs.org/wiki/List_of_quines )还能找到更多由esolang编写的Quine, , 用Malbolge写的Quine ](https://lutter.cc/malbolge/quine.html ), , ? : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								D'< ;_98=6Z43Wxx/.R?Pa
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 12:55:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  代码就像加了密似的, , 规范 ](http://www.lscheffer.com/malbolge_spec.html ),另外虽然这个语言写起来很复杂,但还是有人能用它编出程序的,甚至还有人用[Malbolge Unshackled ](https://esolangs.org/wiki/Malbolge_Unshackled )( ) Lisp解释器 ](https://github.com/iczelia/malbolge-lisp ),实在是恐怖如斯😨。   
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 只能Quine的语言
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  其实想要做出Quine, , , , ? , , : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								#!/bin/cat
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Hello, world!
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  作为脚本执行的结果就是原样输出这段内容, , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## Quine Relay的探索
  
						 
					
						
							
								
									
										
										
										
											2025-09-07 08:47:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  还有一个更加复杂的Quine变种是“Quine接力”( ) , , , , Yusuke Endoh ](https://github.com/mame )(这位还是[IOCCC ](https://www.ioccc.org/ )的冠军之一)创建的[quine-relay ](https://github.com/mame/quine-relay )项目, 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  这种程序写起来会更复杂一些, , , ( ) , 维基百科 ](https://en.wikipedia.org/wiki/Quine_(computing )#Ouroboros_programs )之外,前段时间我还看到过一个不错的[文章 ](https://blog.mistivia.com/posts/2024-09-21-quine/ ), , , , quine-relay ](https://github.com/mame/quine-relay )项目中甚至还包含Brainfuck之类的esolang, , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 12:55:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								## Polyglot Quine的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  除了Quine Relay之外还有一种很复杂的Quine, Polyglot ](https://en.wikipedia.org/wiki/Polyglot_(computing )) Quine, , , , , , , ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  Quine本身就已经很困难了, , , , 这段代码 ](https://github.com/TrAyZeN/polyglot-quine/blob/master/main.c )就是C和Python的Polyglot Quine, , , PyZipQuine ](https://github.com/d0sboots/PyZipQuine )项目, , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-31 16:24:46 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 感想
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  虽然这次探索最终没能完成让包含博客所有内容的压缩包自包含, , , , , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  另外在探索自产生程序的时候,也发现了一些很有意思的网站,比如[Rosetta Code ](https://rosettacode.org/ )以及[Esolang wiki ](https://esolangs.org/ ) ~~(虽然这个网站里被好多小学生写了一堆无聊的东西😂)~~  ,里面有不少有趣的东西,也算是让我大开眼界了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  所以有的时候探索不一定要完成目标,在这个过程中也会收获到很多不错的东西吧😊。