Decimen 光学传输:通过喷泉码二维码用光发送文件
探索 Decimen 光学传输,一个开源工具,使用动画二维码和喷泉码在设备之间传输文件,无需网络连接即可达到高达 130 KB/s 的速度。
在一个文件传输通常意味着云上传、蓝牙配对或 USB 线的世界里,通过光发送数据几乎有些神奇。Decimen 光学传输(decimen.app)正是这样做的:它将你的屏幕变成发射器,将你的相机变成接收器,将文件作为一系列动画二维码流式传输。无需网络、无需配对、无需安装应用程序——只需两台设备面对面。
为什么选择光学传输?
传统的文件传输方法依赖于设备之间的网络路径。但如果你身处安全设施、偏远地区,或者只是想避免建立连接的麻烦呢?光学传输使用了最通用的界面:屏幕和相机。每部智能手机都有它们,并且它们跨平台工作,无需驱动程序或除相机访问之外的权限。
关键洞察是,屏幕到相机的链路没有反向通道。发送方无法知道帧是否被正确接收。这就是喷泉码大放异彩的地方。
喷泉码的魔力
喷泉码,特别是 Luby Transform(LT)码,是一类擦除码,从源文件生成无限流的编码符号。接收方只需要收集一定数量的不同符号——大约是原始文件大小的 1.15 倍——即可重建整个文件,无论哪些符号丢失。
在光学传输的背景下,这意味着发送方可以连续广播帧,接收方可以丢弃帧(由于运动模糊、眩光或相机未对准)而不会影响正确性。丢弃帧只会浪费时间,绝不会影响正确性。这比顺序分块有了巨大改进,在顺序分块中,单个丢失的帧将需要重传机制——在没有反向通道的情况下这是不可能的。
Decimen 的工作原理
该项目使用 TypeScript 构建,并使用 node-qrcode 进行编码,zxing-wasm 进行解码。架构分为 send/ 和 receive/ 目录,并有一个共享模块用于公共工具。
当你在两台设备上打开应用程序时,一台进入 /send/ 页面,另一台进入 /receive/ 页面。发送方选择一个文件(最大 64 MB)或粘贴文本片段。然后,文件在有助于时使用 gzip 压缩,并分成块。每个块被编码成二维码,二维码流在屏幕上动画显示。
接收方的相机连续扫描屏幕,解码出现的每个二维码。解码的块被存储,一旦收集到足够的不同块,文件就被重新组装。SHA-256 哈希在文件提供下载之前验证完整性。
性能和实际结果
该项目报告在真实世界测试中吞吐量为 130.5 KB/s(参见仓库中的截图)。对于视觉通道来说,这令人印象深刻。提取此项目的原始实验在手机到手机之间达到了 128 KB/s。该协议设计高效,喷泉码的使用确保即使帧丢失率很高,只要收到足够的帧,传输就会完成。
入门指南
要自己运行,克隆仓库并安装依赖:
npm install
npm run dev # 带 HMR 的 https 开发服务器
然后在发送设备上打开 https://localhost:5173/send/,在接收手机上打开网络 URL(接受一次自签名证书)。对于生产环境,使用 npm run build 并服务 dist/ 文件夹。
还有一个演示模式(npm run demo),只允许发送捆绑的有效载荷,适用于没有真实文件的测试。
平台怪癖和离线支持
该应用是一个 PWA,因此首次访问后可以离线工作,并且可以安装到 iOS 和 Android 主屏幕。v0.3.0 版本添加了 Android 能力探测、内联媒体播放和共享对话框。该项目还包含一个独立构建,生成两个自包含页面,可以托管在任何地方,甚至可以直接从文件系统打开。
隐私考虑
重要的是要注意,光学传输未加密。发送屏幕上显示的任何内容都可以被任何指向它的相机读取。你获得的属性是没有网络,而不是保密性。如果你需要隐私,你应该在发送前加密文件。
类似项目
光学数据传输的概念已被其他人探索过。README 中提到:
mohankumarelec/airgapped-qr-code-transfer:基于浏览器的二维码文件传输,带有压缩和顺序分块。divan/txqr(2018):Go 中的动画二维码加喷泉码,并提供了关于为什么喷泉码优于顺序循环的出色文章。sz3/libcimbar:完全超越二维码,使用为此通道专门构建的自定义高密度彩色码。
这些项目表明这个想法并不独特,但 Decimen 的实现是精致的、文档完善的,并在 MIT 许可下开源。
结论
Decimen 光学传输是一个使用日常硬件进行非常规用途的迷人例子。它不会取代 Wi-Fi 进行大文件传输,但对于快速、在气隙意义上安全的传输,它是一个简洁的工具。喷泉码的使用是对无反向通道问题的巧妙解决方案,该项目对于任何对光通信或擦除编码感兴趣的人来说都是一个很好的学习资源。
无论你身处高安全环境,还是只想通过空中传输文件来给朋友留下深刻印象,Decimen 都值得一试。而且由于它是开源的,你可以深入研究代码,了解它到底是如何工作的。