开始前,会这些就够了
- 能数出一串 0、1 中有几个 1
- 代码需
Node.js20 或更新版本
遇到不熟悉的词,先看这 1 个解释
- 二维奇偶校验
- 把 0 和 1 排成方格,每行、每列各补一份检查信息。以偶校验为例,先让每行和每列的 1 都是偶数个。若整张格子只有一位翻转,出问题的那一行与那一列会指向同一个位置。
假设两台小设备要传递四个开关状态:1010。途中某个位置从 1 变成 0,接收方仍会得到一串合法的二进制数字,光看外观不知道它已经变了。能否多发一点信息,让接收方至少发现某些差错?
翻一位报错,翻两位会怎样?
先选发送的数据,再勾选传输中翻转的位置。最后一位是自动补上的偶校验位,也可能出错。
加上偶校验位后,发送 10100:前四位是数据,最后一位是 0。
收到:10100,共 2 个 1。通过偶校验。
这次没有设置翻转。
为方便观察,页面同时展示发送方原文和接收结果。真实接收方通常不知道原文与翻转位置;“通过”只说明奇偶性符合规则。此模型不含删位、插位或故意篡改防护。
把总数凑成偶数
偶校验的做法是加上一位,让整段数据中 1 的总数为偶数。1010 有两个 1,因此追加 0,发送 10100。如果原数据有奇数个 1,就追加 1。检查时必须把追加的校验位也算进去;它与数据一起传输,也可能出错。
奇校验则要求总数为奇数,两端选同一套规则才能沟通。本文只用偶校验,并且只讨论固定长度内某些位置的位翻转:0 变 1,或 1 变 0。少一位、多一位、顺序错乱都不是本次模型里的差错。
一次翻转改变奇偶,两次又改回来
翻转一个位置,1 的总数不是增加一,就是减少一,奇偶性一定改变。因此,不论错的是数据位还是校验位,只要最终恰有一个位置不同,偶校验都能报错。三个、五个等奇数个不同位置翻转,也会破坏原来的奇偶性。
但两个位置翻转时,计数可能增加二、减少二或保持不变,奇偶性都不变。例如 10100 的前两个位置翻转后成为 01100,仍有两个 1,却已经是不同的数据。这里数的是最终不同的位置;同一位置翻两次会恢复,不能算成两个不同位置出错。
让同一条消息遇到几种差错
代码在原数据末尾追加校验位,再分别翻转指定位置。下标从左边的 0 开始,所以位置 4 正是最后的校验位。先预测单独翻它会怎样,再比较翻前两个位置的结果。所有输入都只含 0、1,翻转位置也都互不重复。
输出中的 error 表示没有通过偶校验,pass 只表示这条检查规则成立,不能翻译为“内容肯定正确”。程序知道原文是因为我们在制造实验;真正的接收方通常只有收到的那一串,不能拿原文逐位比较来作弊。
function parity(bits) {
return [...bits].reduce((total, bit) => total + Number(bit), 0) % 2;
}
function flip(bits, positions) {
return [...bits].map((bit, i) =>
positions.includes(i) ? String(1 - Number(bit)) : bit
).join("");
}
const data = "1010";
const sent = data + parity(data);
for (const positions of [[], [0], [4], [0, 1], [0, 1, 2]]) {
const received = flip(sent, positions);
console.log(positions.join(",") || "none", received,
parity(received) === 0 ? "pass" : "error");
}怎样运行:保存为 parity.js,运行 node parity.js。使用 Node.js 20 或更新版本,无依赖;示例只处理固定长度的 0、1 字符串。
运行后对照结果
none 10100 pass
0 00100 error
4 10101 error
0,1 01100 pass
0,1,2 01000 error报错之后,为什么不能随便修一位
若接收到 10101,可能原本发送的是 10100,只是最后一位翻转;也可能原本是 00101,只是第一位翻转。这两条原文都满足偶校验,距收到的内容都只差一位。即使事先保证只错一位,接收方仍无法仅凭这一位校验信息决定选哪条原文。
因此,发现差错与纠正差错是不同能力。实际方案可以请求重发,也可以增加更多有安排的校验信息,在规定的差错范围内定位错误。它们同样需要说明范围。单个奇偶校验位既不是任意错误修复器,也不能替代针对故意篡改的真实性验证。
如果另有信息准确指出哪一位翻转,当然可以把那一位翻回去;只是位置来自额外信息,并非这条奇偶规则自己找出的。讨论一种校验能做什么时,要把这些额外条件一起说清楚,不能偷偷借用发送方才知道的原文。
记住这三点
- 单个奇偶校验位能发现奇数个位置翻转。
- 偶数个不同位置翻转会通过这条检查,pass 不是正确证明。
- 知道有错,不等于知道原文或错误位置。
别把例子用过头
- 检查时要连同校验位一起计算。
- 本文结论限定固定长度的翻转位模型。
自己试一小步
把实验数据换成 1101,检查单点与双点翻转。
- 先追加偶校验位。
- 枚举每个单独位置和每对不同位置。
- 保存收到的字符串和校验结果。
做到这些,就算完成
- 包含最后的校验位。
- 每对位置不同且没有重复配对。
- 解释结果,没有把通过校验当作无错证明。
查原始资料
想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。
- 6.004 Computation Structures:1.1 Annotated Slides (新标签页)↗
支持附加奇偶位、单点差错检测、偶数位差错遗漏及检测和纠正的区别。
- 6.02 Lecture 3:Errors, channel codes (新标签页)↗
支持偶校验能发现奇数个位错误、不能发现偶数个位错误,以及单个奇偶位不足以纠正任意单点错误。
找一份资料继续练
先选一项,按下面的范围继续学;不必从头读完整门课程。
Parity Magic:用黑白卡片找出翻错的一格 (新标签页)↗
补一行一列,让每行每列的黑卡数都为偶数;只翻一格并尝试定位。
查看学习准备与访问说明 →