# 文字比對 — 兩段文字，並排比較

兩段文字進來，每處差異都被標出來，逐行、逐詞。沒有一個字被貼進別人的伺服器。

> 比對兩段文字，逐行、逐詞看清每一處差異，並排或單列顯示。比對在你的瀏覽器裡跑，什麼都不上傳——尚未釋出的程式碼從不離開你的機器。

本頁是一個完全在你的瀏覽器裡執行的互動式工具，地址是 https://abox.tools/zh-TW/text-diff/。你交給它的任何內容都不會被上傳。下面是這個頁面用文字對該工具的全部說明；要使用它，請開啟這個地址。

## 你的文字**不會上傳**。這裡根本沒有伺服器。

一次比對就是對兩串字元做算術，就在這個頁面裡做完。演算法是 Myers 的那一個——和 `git diff` 用的是同一個——手寫在 `src/diff.js` 裡，你可以去讀。這個工具沒有任何形式的網路功能，沒有什麼可取，也沒有什麼可發。這一點在這裡格外要緊：人們比對的，是合同、配置檔案和尚未釋出的程式碼，而且總是成對出現。

- ✗ 不上傳
- ✗ 不註冊
- ✗ 無大小限制
- ✓ 斷網可用
- ✓ 開源

## 怎樣在不上傳的前提下比對兩段文字

1. **貼上兩段文字，或者拖進兩個檔案。** 原文在左，改過的在右。同時拖到選擇框上的兩個檔案會按你放下的順序各落一邊；放反了就把兩邊換過來。
2. **選好怎麼讀。** 並排，或者單列。手機上從單列開始，因為並排需要兩欄文字，而手機差不多隻裝得下一欄；反正選單就在旁邊。
3. **忽略無關緊要的。** 空白、大小寫、空行——每一樣都可以單獨忽略，免得一個只是重新排版過的檔案讀起來像改了一百處。預設把沒變的中段摺疊成一個數字，每處改動兩側各留三行。
4. **讀一讀改了什麼。** 刪掉的行標在左邊，新增的行標在右邊；改動行內部，不同的詞會被高亮——兩段文字的比對顯示的是挪動的那個詞，而不是兩整段。
5. **把補丁帶走。** 下載下來的是統一格式的 `.patch`，程式碼評審、`git apply` 和所有差異檢視器認的就是它。複製會把同樣的內容放進剪貼簿。

## 說得更細的版本

[怎樣比對兩個 JSON 檔案](https://abox.tools/zh-TW/guides/compare-two-json-files/): 兩個檔案用同一種方式格式化，鍵排好序，再比對。為什麼生比 JSON 幾乎全是噪音，怎麼在瀏覽器裡把兩邊化成規範形，以及什麼能一路留到補丁裡。

## 工具箱裡還有

- [Base64 編碼解碼](https://abox.tools/zh-TW/base64/): Base64、百分號編碼、HTML 實體、十六進位和反斜槓轉義，雙向都行。沒有一個字被貼進別人的伺服器。
- [文字與檔案分享](https://abox.tools/zh-TW/share-text/): 分享只活在這個開著的分頁裡。讀的人從你的瀏覽器直接取得加密內容，關掉分頁就結束——任何伺服器上都不留一點東西。
- [QR Code 與條碼產生](https://abox.tools/zh-TW/qr-barcode/): 打進去，就變成一個碼。產生過程不往外送任何東西。
- [QR Code 與條碼識讀](https://abox.tools/zh-TW/qr-barcode-reader/): 把鏡頭對準碼，或者把拍下來的圖丟進來。讀這件事只發生在這裡，別處都沒有。

## 常見問題

### 我的文字會被傳到哪裡去嗎？

不會。比對是在你自己的瀏覽器裡、你自己的硬體上執行的函式。這個工具沒有任何形式的網路功能：它從不去取什麼，也從不發出什麼；頁面的 `Content-Security-Policy` 裡寫著它允許聯絡的每一個地址，沒有一個屬於本站。這正是拿它來處理合同、配置檔案或未釋出程式碼的理由：把這類東西貼進別人的比對器，等於把兩個版本一次全交了出去。

### 這個比對到底在做什麼？

它找出把左邊那段文字變成右邊那段所需的最短一組編輯，用的是 Myers 演算法——`git diff` 用的那個。最短，正是讓差異讀得下去的關鍵：在中間插入一行，就該顯示為一次插入，而不是後面每一行都變了。在改動行的內部，不同的詞也會被標出來，所以比較兩段文字時看到的是挪動的那個詞，而不是整整兩段。

### 能比對兩個檔案，而不是兩段貼上嗎？

能。把兩個同時拖到選擇框上，它們會按你放下的順序各落一邊。讀它們的是你的瀏覽器，讀進這個頁面，而這也是它們唯一去的地方。要是放反了，把兩邊換過來就行。

### 比對會輸出什麼，我能應用它嗎？

下載的是一份 unified diff，也就是 `@@ -3,5 +3,5 @@` 那種格式，`git apply`、`patch` 和所有程式碼評審工具都讀得懂。複製則是把同樣的東西放進剪貼簿。螢幕上看到的只是它的一種呈現：左右並排，或者單列，未改動的部分摺疊成一個計數，除非你要求全部展開。

### 能忽略空白、大小寫或空行嗎？

能，每一樣單獨控制。忽略空白後，只是重新排版過的檔案會被比對成沒有變化；忽略大小寫會把 `Error` 和 `error` 當成同一個詞；忽略空行會跳過什麼都不裝的行。這時結果上方的計數會說：把你要求忽略的差異忽略之後，兩邊是一樣的——這和「完全相同」不是同一個論斷，頁面把兩個論斷分得清清楚楚。

### 它能處理多大的比對？

這裡沒有設上限，因為沒有哪臺伺服器在為上限掏錢。兩萬行的兩段文字只改了幾處，眨眼就比完了，因為共同的開頭和結尾在真正運作之前就被裁掉了。兩段毫無共同之處的文字比對會提前停下並說明，而不是花一分鐘去證明本來就明擺著的事；而非常長的比對會畫出前幾千行，其餘交給下載下來的補丁。

### 它免費嗎，需要註冊嗎？

免費，沒有帳號，不用登入，沒有試用期，貼多少也沒有上限。本站帶廣告，經費就是從那裡來的，廣告拿不到任何關於你文字的資訊。

### 斷網能用嗎？

能。頁面載入一次之後斷開網路，它照樣運作。這也是證明「什麼都沒上傳」最省事的辦法，真要把你的文字送出去比對，拔線那一刻就停了。

## 這條隱私承諾怎麼核實

- **你貼進來的東西沒有出去的路。** Content-Security-Policy 裡寫著這個頁面允許聯絡的每一個地址，沒有一個屬於本站。這裡沒有任何可以收走一個貼進來的 token 的接收端，就算有，程式碼裡也沒有把它送過去的東西。
- **這裡不會去取任何東西。** 整個 `src/` 裡沒有 `fetch`，沒有 `XMLHttpRequest`，也沒有 `sendBeacon`。比對是這個頁面裡接收兩串字元、返回哪裡變了的函式。
- **演算法就是那個標準演算法，整個都能讀。** Myers 的最短編輯指令碼演算法，和 `git diff` 用的是同一個，手寫在 `src/diff.js` 裡，每處取捨都寫了註釋。`tests/js/text-diff.test.js` 裡的測試證明：刪除能重建左邊的文字，插入能重建右邊的文字——對一份 diff 來說，「正確」指的就是這個。
- **Google 載入了什麼，又拿不到什麼。** 廣告指令碼和統計指令碼來自 Google，捐助按鈕來自 Buy Me a Coffee。你的文字，一個字元也沒有交給它們。讀取、解析、寫出文字的每一行程式碼都由這個源提供，也都擺在儲存庫裡。
- **斷網也照樣能用。** 斷開網路，這個工具跟原來一模一樣，因為它裡面從來就沒有聯網這一步。這是最省事的一條證明。

**你可以自己核對。**上面這些不用你信。這個頁面是儲存庫裡的模板和配置產生出來的，構建指令碼你能讀，也能自己跑一遍，跑出來的結果就提交在 `dist` 分支上。拿實際發給你的內容，跟你自己從原始碼構建出來的結果對一遍就知道了： https://github.com/A-Box-of-Tools/website

最值得先讀的幾個檔案：`config/site.toml` 裡是 Content-Security-Policy，還有 `src/diff.js`：Myers 演算法、每條改動行內部再跑一遍的逐詞比對，以及三道防線，保證病態的比對凍不住頁面。
