2025-09-01 00:24:46 +08: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),但因为没有合适的方案所以放弃了。而现在对于这个压缩包,我又有了一个特别的想法。事实上在这个下载全站的压缩包中,里面的内容和实际的网站并不完全相同,因为在这个压缩包里缺少了压缩包本身。所以把这个压缩包解压之后直接当作网站打开,会发现下载压缩包的链接是无效的,除非在解压之后把压缩包移动到网站里才行……   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  于是我就在想有没有一种可能可以让压缩包解压之后里面又包含了这个压缩包本身?似乎是个不太可能的事情,但我以前听过类似的东西,也许并非不可能?所以这次就来探索一下吧。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 自包含压缩包的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  在很久之前, ( ) , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  关于原理方面,先看[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 20:55:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  在[Russ Cox](https://swtch.com/~rsc/)写的《[Zip Files All The Way Down](https://research.swtch.com/zip)》文章中, , , , , , , , : 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08: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/)这个谜题中, , : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  另外这个方案是针对使用基于LZ77与哈夫曼编码的DEFLATE压缩算法, , , ( ) , , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  还有一点, ? , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  这么来看既然TGZ可以, ? , , , , , , , , , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 20:55:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  虽然Russ Cox写的文章看起来做不到包含更多内容了, , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  在这篇论文中, , , , , , ( ) , , ( ) , , , ? , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 制作一个嵌套循环的ZIP Quine
  
						 
					
						
							
								
									
										
										
										
											2025-09-17 20:55:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  在实现了常规的ZIP Quine之后, ( ) , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  另外既然这里面有两个压缩包, , , ( ) , , , ( ) ? , ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  现在所有的理论都足够了, , , , ? , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  接下来就该使用论文中提到的生成工具:[zip-quine-generator](https://github.com/ruvmello/zip-quine-generator), , , , , , , , , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  最终我给我的[Mabbs](https://github.com/Mabbs/Mabbs.Project)项目创建了[Infinite Mabbs](https://github.com/Mabbs/Mabbs.Project/releases/tag/Final-version)这个发布,生成的文件也可以在[这里](/assets/Mabbs.zip)下载,这也算是不枉我研究半天这个论文了😆。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 自产生程序的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  说起来自包含压缩包为什么叫做ZIP Quine? ? , , , , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 实现Quine的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  那么什么是自产生程序?简单来说就是程序的源代码和程序的输出完全相同的程序,而且通常来说不允许通过读取/输入源代码的方式实现。按照一般的想法, , , , , , , , : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```python
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								c = 'c = %r; print(c %% c)'; print(c % c)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  这里的变量中就以数据的形式存储了程序的代码,而在输出的时候除了变量内的代码,又通过引用的方式又把变量的内容放回到赋值的地方,所以它的输出就和原本的代码一样了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  其实Quine的实现思路都差不多是这样, , , , , , , , , , ? : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								D'< ;_98=6Z43Wxx/.R?Pa
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 20:55:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  代码就像加了密似的, , ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## 只能Quine的语言
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  其实想要做出Quine, , , , ? , , : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								#!/bin/cat
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Hello, world!
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  作为脚本执行的结果就是原样输出这段内容, , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								## Quine Relay的探索
  
						 
					
						
							
								
									
										
										
										
											2025-09-07 16:47:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								  还有一个更加复杂的Quine变种是“Quine接力”( ) , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  这种程序写起来会更复杂一些, , , ( ) , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-17 20:55:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								## Polyglot Quine的探索
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  除了Quine Relay之外还有一种很复杂的Quine, , , , , , , , ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  Quine本身就已经很困难了, , , , , , , , , , , 
							 
						 
					
						
							
								
									
										
										
										
											2025-09-01 00:24:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# 感想
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								  虽然这次探索最终没能完成让包含博客所有内容的压缩包自包含, , , , , , , , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  另外在探索自产生程序的时候,也发现了一些很有意思的网站,比如[Rosetta Code](https://rosettacode.org/)以及[Esolang wiki](https://esolangs.org/) ~~(虽然这个网站里被好多小学生写了一堆无聊的东西😂)~~  ,里面有不少有趣的东西,也算是让我大开眼界了。   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								  所以有的时候探索不一定要完成目标,在这个过程中也会收获到很多不错的东西吧😊。