地球与邻近星系之间,每毫秒都有数以万亿计的消息飞驰而过。 但要在如此遥远的距离上传输,并不容易。 恼人的太阳耀斑、时间扭曲、杂散的力场,甚至一只太空蝴蝶扇动翅膀,都可能让某个比特在传输过程中随机发生改变。
现在想象一下后果:
检测出损坏的消息不只是重要,而是至关重要。 接收方_必须_在灾难降临之前知道哪里出了问题。
但怎么做到呢? 宇宙各地的科学家和工程师已经和这个问题斗争了亿万年。 整个宇宙的人工智能超级集群都在不停运算这些数据。 直到有一天,一个传说重新浮出水面:一种古老而强大的方法,在调试论坛上被人低声提起,被那些见识过太多的工程师们反复念叨……
奇偶校验位!
一种如此简单、如此强大的方法,也许正好能拯救星际通信。
你的任务是帮助实现
奇偶校验位是一种检测传输错误的简单方法。
发送器和接收器每次只能发送和接收恰好八位(包括奇偶校验位)。
奇偶校验位的取值使得每次传输中 1 的个数为偶数,而且奇偶校验位始终是从右边数起的第一位。
因此,如果接收器收到 11000001、01110101 或 01000000(即一次传输中 1 的个数为奇数),它就知道出错了。
不过,消息很少这么短;当消息较长时,就需要按序列来传输。
例如,考虑消息 11000000 00000001 11000000 11011110(十六进制为 C0 01 C0 DE)。
由于每次传输恰好包含八位,因此其中最多只能有七位数据和一位奇偶校验位。 所以每七位数据之后都必须插入一个奇偶校验位:
11000000 00000001 11000000 11011110
↑ ↑ ↑ ↑ (7th bits)
这条消息的传输序列如下:
1100000_ 0000000_ 0111000_ 0001101_ 1110
↑ ↑ ↑ ↑ (parity bits)
序列中第一次传输的数据(1100000)有两个 1(偶数个),因此奇偶校验位为 0。
第一次传输变成 11000000(十六进制为 C0)。
下一次传输的数据(0000000)中 1 的个数为零(同样是偶数个),因此奇偶校验位仍然是 0。
第二次传输由此变成 00000000(十六进制为 00)。
接下来两次传输的数据(0111000 和 0001101)有三个 1。
它们的奇偶校验位被设为 1,使整个传输中 1 的个数为偶数。
它们的传输形式是 01110001 和 00011011(十六进制为 71 和 1B)。
最后一次传输(1110)只有四位数据。
由于每次传输恰好是八位,而奇偶校验位在最右边,因此要先补三个 0,再加上奇偶校验位,凑足八位。
现在它看起来是这样(其中 _ 代表奇偶校验位):
1110 000_
↑↑↑ (added 0 bits)
1 的个数又是奇数,所以奇偶校验位为 1。
序列中最后一次传输变成 11100001(十六进制为 E1)。
这条消息的完整传输序列是 11000000 00000000 01110001 00011011 11100001(十六进制为 C0 00 71 1B E1)。