我把一个网站存储在一个 favicon 中
不久前,我写了一篇关于将两个字节存储在鼠标的 DPI 注册表中的文章。这并没有用处,也不实用。但它对我的大脑产生了一些不幸的影响。一旦你成功地将数据隐藏在一个不属于它的地方,你就开始把所有东西都视为潜在的存储空间。监视器是存储。键盘是存储。BIOS 启动画面可能也是存储。favicon 也是存储。是的,我们就在这里。每个网站都有一个 favicon。它是你浏览器标签中的那个小图标。通常你只需上传一次,然后再也不考虑它了。但 favicon 只是一个图像。图像只是像素。而像素只是一串字节。所以我自然想知道我是否可以在它里面存储一些东西。想法 我的第一个想法是隐写术。隐写术基本上是关于在图像中隐藏数据而不让其明显。你拍摄一张完全正常的照片,并修改几个比特,使其秘密包含一条消息。favicon 本身(至少在我的演示中)不需要看起来像一个图标。它可以变成纯存储。每个像素都有红、绿和蓝的值。这是三个字节。如果我想存储文本,我可以直接将文本的 UTF-8 字节写入 RGB 通道。浏览器不关心这些字节代表什么。在浏览器看来,它们是颜色。对我来说,它们是 HTML。构建一个 favicon 网站 我从一个小的 HTML 负载开始:<h1>网站在一个 favicon 中</h1> <p>你现在阅读的所有内容都是从 favicon 像素解码而来的。</p> 这个过程非常简单。首先,我使用 TextEncoder 将 HTML 转换为字节。然后,在前面添加四个字节,以包含负载长度。长度头是重要的,因为图像本身可能在末尾包含未使用的像素。如果没有长度值,就没有办法知道真正的负载在哪里结束。一旦我有了字节数组,我就开始填充像素。第一个字节变成第一个像素的红色通道。第二个字节变成绿色通道。第三个字节变成蓝色通道。然后是下一个像素。再下一个。又下一个……最终整个 HTML 文档以彩色像素的形式存在。生成的图像看起来像视觉噪音。非常小 说实话,最让我惊讶的不是它能成功,而是生成的图像有多小。负载最终为 208 字节。加上 4 字节的头,总共 212 字节。由于每个像素存储三个字节,我需要:212 字节总数 71 像素 一幅足够容纳它们的正方形图像 能够工作的最小正方形是 9x9 像素。那只有 81 像素。最终的统计数据如下: 负载:208 字节 图像大小:9x9 像素 容量:239 字节 已用:87% 不知何故,一个完整的小网站(好吧,有一些样式的 html)装入了一个比通常的 favicon 更小的图像中。 从 favicon 中读取网站 存储数据仅仅是问题的一半。另一个问题是如何将其取回。浏览器已经具备了所需的一切。favicon 被作为图像加载。图像被绘制到画布上。画布 API 允许 JavaScript 读取每个像素。一旦我有了像素数据,我只需反向处理。读取 RGB 值。重构字节数组。读取前四个字节以确定负载长度。提取负载。解码 UTF-8 文本。此时我得到了原来的 HTML。浏览器从其自己的 favicon 中读取了一个网站。 重要的附带说明 Favicon 实际上并不包含整个网站。它包含了一个网站的内容。你仍然需要一个小的引导加载程序来解码图像。没有 JavaScript,favicon 只是一个 PNG(其中包含你的网站内容)。为了展示这个场景,网站包含一个“渲染网站”按钮。它读取 favicon,解码 HTML,并用重构的内容替换页面。 这有用吗?不,当然没有。你可以存储的数据量非常小。该页面需要 JavaScript 来引导自己。还有数十种更好的方法来分发一个小的 HTML 文档。但最终这一切都是在测试极限,对吧?favicon 感觉像是一种非常具体的东西。它应该是一个图标。但最终它可以只是一个 PNG。而一个 PNG 文件基本上只是字节。这可能是我构建的最小的网站……这是网站的链接:https://www.timwehrle.de/labs/favicon-site/ 如果你想看看它是如何工作的:https://github.com/timwehrle/favicon
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡