开发者生态
morning
我将网站存储在网站图标中
2026-06-20
1 阅读
theanonymousone
不久前,我写了一篇关于在鼠标的 DPI 寄存器中存储两个字节的文章。这没有用。这不切实际。但这对我的大脑做了一些不幸的事情。一旦您成功地将数据隐藏在不属于的地方,您就开始将所有内容视为潜在的存储空间。显示器就是存储。键盘就是存储。 BIOS 初始屏幕(可能)是存储。网站图标是存储空间。是的,我们到了。每个网站都有一个网站图标。它就是浏览器选项卡中的那个小图标。通常你上传一次之后就不会再想了。但。网站图标只是一个图像。图像只是像素。像素只是字节。所以我当然想知道我是否可以在其中存放一些东西。我的第一个想法是隐写术。隐写术基本上是将数据隐藏在图像中而不使其显而易见。你拍了一张完美的普通照片并修改了一些位,这样它就秘密地包含了一条信息。图标本身(至少在我的演示中)不需要看起来像一个图标。它可以成为纯粹的存储。每个像素都有红色、绿色和蓝色值。那是三个字节。如果我想存储文本,我可以只获取文本的 UTF-8 字节并将它们直接写入 RGB 通道。浏览器不关心这些字节代表什么。对于浏览器来说它们是颜色。对我来说它们是 HTML。构建一个网站图标网站 我从一个很小的 HTML 有效负载开始:
网站图标中的网站
您现在阅读的所有内容都是从网站图标像素解码的。
这个过程非常简单。首先,我使用 TextEncoder 将 HTML 转换为字节。然后我在前面添加四个包含有效负载长度的字节。长度标头很重要,因为图像本身可能在末尾包含未使用的像素。如果没有长度值,就无法知道真正的有效负载在哪里停止。一旦获得字节数组,我就开始填充像素。第一个字节成为第一个像素的红色通道。第二个字节成为绿色通道。第三个字节成为蓝色通道。然后是下一个像素。还有下一个。接下来……最终整个 HTML 文档以彩色像素的形式存在。生成的图像看起来像视觉噪声。非常小 老实说,最令我惊讶的并不是它有效。这是生成的图像有多小。有效负载最终为 208 字节。添加 4 字节标头后,总数达到 212 字节。由于每个像素存储三个字节,因此我需要: 212 个字节,总共 71 个像素 足够大以容纳它们的正方形图像 最小的正方形是 9x9 像素。那只有 81 像素。最终统计数据如下所示: 有效负载:208 字节 图像大小:9x9 像素 容量:239 字节 使用率:87% 不知怎的,整个小网站(好吧,带有一些样式的 html)适合放在比通常的图标更小的图像中。读回网站 存储数据只是问题的一半。另一半正在拿回来。浏览器已经具备了这方面所需的一切。网站图标作为图像加载。图像被绘制到画布上。 canvas API 允许 JavaScript 读取每个像素。一旦获得像素数据,我只需反转该过程即可。读取 RGB 值。重建字节数组。读取前四个字节以确定有效负载长度。提取有效负载。解码 UTF-8 文本。那时我又拥有了原始的 HTML。浏览器从自己的图标中读取网站。重要的一点是网站图标实际上并不包含整个网站本身。它包含网站的内容。您仍然需要一个小型引导加载程序来解码图像。如果没有 JavaScript,网站图标只是一个 PNG(其中包含您的网站内容)。为了显示此场景,该站点包含一个“渲染网站”按钮。它读取图标,解码 HTML,并用重建的内容替换页面。这有用吗?不,当然不是。您可以存储的数据量很小。该页面需要 JavaScript 来引导自身。有许多更好的方法来分发小型 HTML 文档。但最终还是要测试边界,对吗?网站图标感觉像是一个非常具体的东西。它应该是一个图标。但最终它可能只是一个PNG。 PNG 文件基本上只是字节。这可能是我建立的最小的网站......这是该网站的链接:https://www.timwehrle.de/labs/favicon-site/ 如果您想了解它是如何工作的:https://github.com/timwehrle/favicon