# QR File Transfer

> 不用網路、不用傳輸線：檔案編成一連串 QR Code 在螢幕上播放，另一台裝置用鏡頭掃過就能收檔。Fountain code 讓漏拍幾格也無妨，CRC-32 驗證完整性，全程不上傳。

- URL: https://bytescope.dev/zh-Hant/qr-file-transfer/
- Locale: zh-Hant · Also: [en](https://bytescope.dev/en/qr-file-transfer.md) · [ja](https://bytescope.dev/ja/qr-file-transfer.md)
- Runs: 檔案的切塊、編碼與顯示全都在你的瀏覽器完成，不會上傳任何資料。
- Requires: Any modern browser with camera access, desktop and mobile. Nothing is sent anywhere; frames are processed locally.
- Updated: 2026-09-08

## What it does

在傳送端挑一個檔案，頁面會把它切成一塊塊，用 Luby Transform 這種 fountain code 編碼，然後以每秒 5 到 20 格的速度，在螢幕上無限輪播 QR Code。接收端開同一個頁面，把鏡頭對準對方的螢幕：每解出一格，進度條就往前走；等收到的區塊夠了，檔案當場重組、用 `CRC-32` 核對無誤，直接給你下載。兩台裝置之間唯一跨過去的東西是光 —— 沒有網路、沒有伺服器、沒有配對、沒有線、沒有帳號，所以作業系統隨便配：只要開得了網頁，就傳得了檔。

### 為什麼漏拍一格也不痛不癢

這條通道是徹底的單向：接收端沒有任何辦法喊「第 37 格再來一次」。Fountain code 就是為這種處境發明的 —— 它不是把區塊 1、2、3 照順序送出去，而是讓每一格 QR Code 都裝著好幾個區塊的隨機混合；只要收集到夠多格，隨便哪些格都行，整個檔案就拼得回來。鏡頭晃了、對焦飄了、你剛好眨了眼 —— 什麼都沒損失，後面的格子會用不同的組合把同樣的資訊再帶過來一次。就算掉了四成的格子，傳輸照樣完成，只是多花一點時間。這也是傳送端會一直循環播放的原因：它不知道對面收到了什麼，而用了 fountain code，它也不需要知道。

### 老實講數字 —— 這條通道適合什麼、不適合什麼

這是一條窄通道：每秒幾 KB 到幾十 KB，上限卡在相機快門和螢幕更新率。所以它的甜蜜點是文字類的東西 —— 設定檔、SSH 金鑰、憑證、錢包助記詞、小型文件，大到幾 MB 都行；相簿和影片就別想了。它真正發光的場景，是同一個房間裡兩台怎樣都連不起來的機器：沒有共用 Wi-Fi、被鎖死什麼都不能裝的公司筆電、air gap 隔離的主機、兩套死不往來的作業系統。傳送端在任何瀏覽器都能跑（就只是在 canvas 上畫 QR Code）；接收端在有 `BarcodeDetector` API 的 Chromium 系瀏覽器最快 —— Chrome、Edge、Opera、Android 版 Chrome —— 其他瀏覽器會退回 JavaScript 解碼器，能用但比較慢。另外有一條刻意劃下的界線：傳輸大小有上限，也沒有批次或自動化模式。因為一條無人看管、不設上限的螢幕對鏡頭通道，就是把資料搬出 air gap 主機的外洩管道，我們不打算幫這種事做出一個好用的工具。

## Limits

Does not transfer large files quickly (QR bandwidth is a few KB/s); use device-transfer for anything above a few hundred kilobytes.

## FAQ

### 它到底能傳多大的檔案？要花多久？

抓每秒幾 KB 到幾十 KB 來估 —— 天花板卡在相機能多快看清楚一個不停變化的螢幕，不是編碼本身。40 KB 的設定檔幾秒鐘就過去；幾百 KB 的憑證包大概一兩分鐘；幾 MB 是實際的上緣，而且工具本身就設了硬性的大小上限。再大的東西 —— 照片、影片、壓縮檔 —— 這就是錯的工具了；與其讓你盯著進度條一小時，我們寧可先把話講白。

### 接收端已經收完了，傳送端為什麼還在播 QR Code？

因為傳送端是真的無從得知。這條通道是單向的 —— 光從螢幕走到鏡頭，什麼都不會傳回來 —— 所以傳送頁面就是一直循環播放 fountain code 編出來的格子，直到你手動停下。這不是 bug，正是讓整件事不用配對就能成立的那個設計。接收端一顯示下載完成，你隨時可以把傳送端停掉。

### 我的檔案會被上傳到哪裡嗎？

不會 —— 而且不是「我們保證伺服器會刪掉」那種不會：這條路徑上根本沒有伺服器。檔案在傳送端的瀏覽器裡讀取、切塊、編碼，以光的形式跨過去，再在接收端的瀏覽器裡重組。兩邊都可以打開 DevTools 的 Network 分頁自己驗證。檔案本身和檔名都不會離開你的裝置；網站分析唯一會記錄的，是「有一次傳輸發生」以及一個很粗略的大小級距。

### 為什麼接收端在我的瀏覽器動不了？

鏡頭這一側用 `BarcodeDetector` API 解碼最快，而它是 Chromium 專屬的：桌面版 Chrome、Edge、Opera，加上 Android 版 Chrome。缺這個 API 的瀏覽器 —— Firefox 和 Safari —— 頁面會退回 JavaScript 的 QR 解碼器，能動，但每秒讀得到的格數變少，傳輸就拖長。另外瀏覽器跳出相機權限詢問時要記得允許。傳送端就沒這些條件：在 canvas 上畫 QR Code，任何瀏覽器都辦得到。

### 這安全嗎？別人的鏡頭是不是也讀得到？

讀得到 —— 這句話要講得夠直白：看得到螢幕的人，就拿得到這個檔案。QR 格子沒有加密，這條通道的隱私，就是你所在那個房間的物理隱私。如果檔案真的重要 —— 金鑰、助記詞、帳密 —— 傳之前先自己加密（`age` 檔、帶密碼的 7z、GPG 都行），密碼再走另一條路送。順帶一提，大小上限和「沒有批次、沒有自動化」都是刻意的：一條可以無人看管的螢幕對鏡頭通道，等於幫 air gap 主機開了一條外洩水管，我們不會做這種東西。
