# 文本比对 — 两段文本，并排比较

两段文本进来，每处差异都被标出来，逐行、逐词。没有一个字被贴进别人的服务器。

> 比对两段文本，逐行、逐词看清每一处差异，并排或单列显示。比对在你的浏览器里跑，什么都不上传——尚未发布的代码从不离开你的机器。

这是一个浏览器交互工具，地址是 https://abox.tools/zh/text-diff/。文件在运行该浏览器的设备上处理。主动分享和可选联网功能都在页面上说明。下文是它的文字说明；使用工具请打开该地址。

## 你的文本**在浏览器里处理**，无须上传处理。

一次比对就是对两串字符做算术，就在这个页面里做完。算法是 Myers 的那一个——和 `git diff` 用的是同一个——手写在 `src/diff.js` 里，你可以去读。这个工具没有任何形式的网络功能，没有什么可取，也没有什么可发。这一点在这里格外要紧：人们比对的，是合同、配置文件和尚未发布的代码，而且总是成对出现。

- ✗ 不上传
- ✗ 不注册
- ✗ 无大小限制
- ✓ 断网可用
- ✓ 开源

## 怎样在不上传的前提下比对两段文本

1. **贴上两段文本，或者拖进两个文件。** 原文在左，改过的在右。同时拖到选择框上的两个文件会按你放下的顺序各落一边；放反了就把两边换过来。
2. **选好怎么读。** 并排，或者单列。手机上从单列开始，因为并排需要两栏文字，而手机差不多只装得下一栏；反正菜单就在旁边。
3. **忽略无关紧要的。** 空白、大小写、空行——每一样都可以单独忽略，免得一个只是重新排版过的文件读起来像改了一百处。默认把没变的中段折叠成一个数字，每处改动两侧各留三行。
4. **读一读改了什么。** 删掉的行标在左边，新增的行标在右边；改动行内部，不同的词会被高亮——两段文字的比对显示的是挪动的那个词，而不是两整段。
5. **把补丁带走。** 下载下来的是统一格式的 `.patch`，代码评审、`git apply` 和所有差异查看器认的就是它。复制会把同样的内容放进剪贴板。

## 说得更细的版本

[怎样比对两个 JSON 文件](https://abox.tools/zh/guides/compare-two-json-files/): 两个文件用同一种方式格式化，键排好序，再比对。为什么生比 JSON 几乎全是噪音，怎么在浏览器里把两边化成规范形，以及什么能一路留到补丁里。

## 工具箱里还有

- [Base64 编码解码](https://abox.tools/zh/base64/): Base64、百分号编码、HTML 实体、十六进制和反斜杠转义，双向都行。没有一个字被贴进别人的服务器。
- [文本与文件分享](https://abox.tools/zh/share-text/): 分享只活在这个打开的标签页里。读的人从你的浏览器直接取走加密内容，关掉标签页就结束——任何服务器上都不留一点东西。
- [二维码与条形码生成](https://abox.tools/zh/qr-barcode/): 打进去，就变成一个码。生成过程不往外送任何东西。
- [二维码与条形码识读](https://abox.tools/zh/qr-barcode-reader/): 把摄像头对准码，或者把拍下来的图丢进来。读这件事只发生在这里，别处都没有。

## 常见问题

### 我的文本会被传到哪里去吗？

不会。比对是在你自己的浏览器里、你自己的硬件上运行的函数。这个工具没有任何形式的网络功能：它从不去取什么，也从不发出什么；页面的 `Content-Security-Policy` 里写着它允许联系的每一个地址，没有一个属于本站。这正是拿它来处理合同、配置文件或未发布代码的理由：把这类东西贴进别人的比对器，等于把两个版本一次全交了出去。

### 这个比对到底在做什么？

它找出把左边那段文本变成右边那段所需的最短一组编辑，用的是 Myers 算法——`git diff` 用的那个。最短，正是让差异读得下去的关键：在中间插入一行，就该显示为一次插入，而不是后面每一行都变了。在改动行的内部，不同的词也会被标出来，所以比较两段文字时看到的是挪动的那个词，而不是整整两段。

### 能比对两个文件，而不是两段粘贴吗？

能。把两个同时拖到选择框上，它们会按你放下的顺序各落一边。读它们的是你的浏览器，读进这个页面，而这也是它们唯一去的地方。要是放反了，把两边换过来就行。

### 比对会输出什么，我能应用它吗？

下载的是一份 unified diff，也就是 `@@ -3,5 +3,5 @@` 那种格式，`git apply`、`patch` 和所有代码评审工具都读得懂。复制则是把同样的东西放进剪贴板。屏幕上看到的只是它的一种呈现：左右并排，或者单列，未改动的部分折叠成一个计数，除非你要求全部展开。

### 能忽略空白、大小写或空行吗？

能，每一样单独控制。忽略空白后，只是重新排版过的文件会被比对成没有变化；忽略大小写会把 `Error` 和 `error` 当成同一个词；忽略空行会跳过什么都不装的行。这时结果上方的计数会说：把你要求忽略的差异忽略之后，两边是一样的——这和“完全相同”不是同一个论断，页面把两个论断分得清清楚楚。

### 它能处理多大的比对？

这里没有设上限，因为没有哪台服务器在为上限掏钱。两万行的两段文本只改了几处，眨眼就比完了，因为共同的开头和结尾在真正干活之前就被裁掉了。两段毫无共同之处的文本比对会提前停下并说明，而不是花一分钟去证明本来就明摆着的事；而非常长的比对会画出前几千行，其余交给下载下来的补丁。

### 它免费吗，需要注册吗？

免费，没有账号，不用登录，没有试用期，贴多少也没有上限。本站带广告，经费就是从那儿来的，广告拿不到任何关于你文本的信息。

### 断网能用吗？

能。页面加载一次之后断开网络，它照样干活。这也是证明“什么都没上传”最省事的办法，真要把你的文本送出去比对，拔线那一刻就停了。

## 这条隐私承诺怎么核实

- **处理在这个浏览器里完成。** 本工具在浏览器里处理输入和结果，处理代码不把它们上传去处理。Content-Security-Policy 限制可用资源和连接目的地，但已允许的主机仍可接收请求。策略不检查载荷，不能单独证明什么都没有发出。请把具体操作的请求与源码核对，或断网完成该本地操作。
- **这里不会去取任何东西。** 整个 `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 算法、每条改动行内部再跑一遍的逐词比对，以及三道防线，保证病态的比对冻不住页面。
