第 3 章
排除法
示波器探头按在接收链路最后一极,波形平稳如死水。老魏没说话,把探头移到下一级,眼睛盯着屏幕上那条几乎不动的绿色轨迹。
“馈源正常。”他说,声音从喉咙里挤出来。
林岸站在他身后,目光越过老魏的肩膀落在示波器上。控制室里的空调在墙壁内部发出一阵低频嗡鸣,像某种大型动物翻了个身。他闻到了老魏棉袄上那股陈年机油味,混合着冷湖特有的沙土气。
“再往前一级。”林岸说。
老魏没动。他右手捏着探头,指节发白,袖口磨出的毛边在示波器荧光里微微发亮。“你知道这一级是什么。”
“低噪声放大器。测。”
老魏把探头按上去。波形跳了一下,然后重新归于平稳。绿色轨迹像一条被拉直了的心脏监护线,没有起伏,没有杂波,干净得让人不舒服。
“正常。”老魏说。
林岸转身走向自己的工位。他瞥了一眼墙上的时钟——01:47。沈岷的指令还在屏幕角落闪烁,那行“冻结全部数据权限”的字样像一个倒计时器,每过一秒就亮一下。他还有不到十分钟决定是否先复制一份原始数据。
“先备份。”林岸说。
老魏正在拆接收链路的后端模块,听到这话停下手里的螺丝刀。“备份?沈岷的指令是冻结。你现在备份,就是违抗。”
“指令还没生效。我现在备份,是执行生效前的正常数据流程。”
老魏把螺丝刀放下,转过身来。他的右肩比左肩低半寸,在控制室的荧光灯下,整个人像一棵被风吹斜了的老树。“林岸,你什么时候开始玩这种文字游戏了?”
“从氢原子钟说‘正常’开始。”
老魏盯着他看了两秒,然后重新拿起螺丝刀。“要备份你自己备份。我先把硬件查完。设备的问题不查清楚,备份了也是白搭。”
林岸没再说话。他调出数据存储阵列的接口,把原始电压数据导出到本地硬盘。进度条慢慢爬升,百分之七、百分之十二、百分之十九。他盯着那个数字,脑子里在计算沈岷的指令还有多久生效。七分钟。六分半。
备份完成。林岸把硬盘放进抽屉,锁上。抽屉的锁有点涩,他用了两下力才把钥匙拔出来。
“后端数字转换模块,正常。”老魏的声音从机柜方向传来,“林岸,你过来看一下这个。”
林岸走过去。老魏指着一块板卡上的测试点,示波器上的波形呈现出教科书级别的方波,上升沿和下降沿干净利落,没有任何抖动。
“这块板我上个月刚换过。”老魏说,“全新的。你看这波形,跟出厂测试一样。”
“接收链路所有硬件指标都正常?”林岸问。
老魏没有立刻回答。他慢慢把示波器探头从测试点上移开,把板卡推回机柜,动作很慢,像在拖延什么。然后他直起身,用棉袄袖口擦了擦额头上并不存在的汗。
“从天线馈源到数字后端,每一级都测过了。”他的声音比之前低了一些,“增益正常,噪声系数正常,驻波比正常,时钟同步正常。全都正常。”
林岸等着他说下去。
老魏把示波器关掉,屏幕上的绿色轨迹缩成一个小点,然后消失。“这玩意儿不该正常。林岸,你知道我的意思。收到一个不可能的信号,设备应该有个说法。杂散、串扰、镜像响应、地线环路——什么都行。但偏偏什么都没有。”
控制室里的风扇嗡鸣声似乎大了一点。林岸环顾四周,十几排机柜的指示灯稳定地亮着,绿色,绿色,绿色。没有一块红色告警。
“设备故障的假设,”林岸说,“正式排除。”
老魏点了点头,动作很轻,像是承认了某种他不愿意承认的东西。
林岸回到工位,打开数据写入日志。他的手指在键盘上敲击,发出清脆的声响。老魏拖了把椅子坐过来,搪瓷杯放在桌角,杯底与桌面隔着一层冷凝水,拿起来时发出细微的“啵”声。
“现在查数据。”林岸说,“如果硬件没问题,那问题可能出在数据层。要么有人篡改了数据,要么数据在写入时就被污染了。”
“篡改数据得有人进来。”老魏说,“或者远程进入。DSO有权限。”
林岸的手停在键盘上。他想起沈岷的指令,想起那行闪烁的“冻结全部数据权限”。如果DSO想掩盖什么,冻结数据确实是一个有效的手段。但他没有说出来。
“先查写入日志。”他说。
写入了。日志在屏幕上滚动,一条条记录像流水一样滑过。时间戳、操作员ID、操作类型、校验和。林岸把回声信号的原始数据文件调出来,定位到它被写入存储阵列的时间。
“看这里。”林岸指着屏幕,“文件写入时间是昨天凌晨两点十七分。操作员ID:LAn。校验和完整。”
“LAn是你。”老魏说。
“这条写入记录是我收到信号后,手动触发的一次原始数据保存。但信号本身在接收机缓存里就已经存在了。它的最初捕获时间是三天前。”
老魏把搪瓷杯端起来,喝了一口。杯子里不知道是茶还是什么东西,液体颜色很深。他放下杯子,用粗糙的手指在桌面上画了一个圈。
“接收机缓存的数据,谁动过?”
“缓存数据有独立的日志。”林岸调出另一份记录,“从信号捕获到写入存储阵列,中间有十七次读取操作。每一次都有操作员ID和权限验证。全部合法。”
“全部合法。”老魏重复了一遍,语气像在嚼一块嚼不烂的东西,“所以没有人篡改数据。数据从捕获到存储,全链路的权限记录都是干净的。”
“数据篡改的假设,”林岸说,“排除。”
老魏沉默了很久。他从口袋里掏出一包烟,在手里捏了捏,没抽,又放回去。控制室里禁止吸烟,但林岸知道老魏有这个习惯——遇到想不通的事,就把烟捏在手里,像捏一个不确定的答案。
“林岸。”老魏的声音比之前更低了,“你有没有想过,如果设备没问题,数据也没问题,那有问题的到底是什么?”
林岸没有回答。他的目光落在屏幕上,日志还在滚动。他不想接这个话茬,因为接下去的方向,两个人都知道是什么。
“我再比对一下信号内容。”林岸说。
他调出回声信号的完整频谱图,把校准序列的原始版本放在旁边做对比。两个窗口并排排列,波形在屏幕上缓慢滚动。前几百个比特完全一致,分毫不差。林岸的手指在触控板上滑动,把画面放大。
然后他停住了。
在频谱图的边缘,大约在第七百三十三个比特的位置,有一段编码出现了偏差。很小,小到如果不放大到最大分辨率根本看不出来。但林岸看到了。那不是一个随机的错误——那是一个有规律的偏移模式,总共九个比特,排列方式非常特别。
他的手指停在触控板上。
九个比特。前三个是同步码,中间四个是数据块,最后两个是校验位。这个结构本身是标准的,但数据块的四个比特用了非标准的加权方式。林岸盯着那四个比特的位置,感觉自己的呼吸变浅了。
那是他三年前调试校准序列生成器时,随手写下的一个习惯性标记。当时他在测试序列的自相关特性,需要快速识别某个测试版本,就在数据块里加了一个非标准的偏移量。那个偏移量没有任何技术意义,只是他自己能认出来的一个记号。
他没有告诉过任何人。没有写进任何文档。甚至连他自己都快忘了——直到现在,它出现在一个来自未来的信号里。
“你发现了什么?”老魏凑过来。
林岸的手指从触控板上移开,动作有些僵硬。“一段编码偏差。很小。”
“多大?”
“九个比特。”
老魏看了看屏幕,又看了看林岸。“九个比特的偏差,在几百万个比特的序列里,你怎么一眼就看出来了?”
林岸没有回答这个问题。他关掉了比对窗口,把频谱图缩小,屏幕重新回到日志界面。他的心跳在胸腔里撞击,像某个被困在肋骨里的东西在敲门。
“可能是某种干扰。”林岸说。
“干扰不会这么精确。”老魏说,“九个比特,位置固定,模式固定。这不是干扰。”
“我再确认一下。”林岸说。
老魏没再追问。他靠在椅背上,用那种修了三十多年设备的人特有的耐心,看着林岸在键盘上敲击。但林岸能感觉到老魏的目光,像一把慢慢拧紧的螺丝刀。
时间在控制室里走得很慢。每一分钟都被风扇的嗡鸣声拉长。林岸重新打开比对窗口,把那段九个比特的编码单独提取出来,转换成十六进制。屏幕上显示出一行字符:
3F 7A 2B 5C
他盯着那行字符,喉咙里泛起一股酸味。3F 7A 2B 5C。他不用查任何记录就知道这是什么。这是他三年前调试时随手写下的一个标记,用的是他自己设计的一套非标准加权方式。那四个字节对应一个特定的测试版本号,只有他知道这个版本号意味着什么。
“怎么了?”老魏问。
林岸没有回答。他关掉十六进制窗口,手指在键盘上悬着,不知道该按什么。然后他慢慢摘下眼镜,用衣角反复擦拭镜片,动作机械而缓慢。
“林岸。”老魏把椅子往前挪了挪,“你看到什么了?”
“没什么。”林岸把眼镜重新戴上,镜片上没有灰尘,他却觉得视线有些模糊,“一段编码异常。可能是序列生成器的某些参数漂移导致的。”
“参数漂移不会产生有规律的编码模式。”老魏说,“我修了三十多年设备,参数漂移长什么样我比你清楚。那九个比特,是有意写进去的。”
林岸没有反驳。他低头看着键盘,手指无意识地摸着方向键的边缘。控制室里的空气突然变得很稠,像有什么东西在慢慢凝固。
“老魏。”他抬起头,“你有没有在用某种非标准的方式修改过校准序列?”
“没有。”老魏回答得很快,语气里带着一丝被冒犯的警觉,“校准序列是硬件随机数发生器生成的,我碰都不会碰。那是你的领域。”
“你有没有见过其他人这么做过?”
“没有。”老魏的声音更硬了,“林岸,你到底看到什么了?那九个比特是什么东西?”
林岸沉默了一会儿。他可以选择说谎,可以编一个技术解释,可以把话题引开。但老魏的眼睛一直看着他,那双修了三十多年设备的手放在膝盖上,指甲缝里还嵌着陈年的焊锡屑。林岸知道,这个人对“不对劲”的直觉比任何仪器都敏锐。
“那九个比特,”林岸说,“是我自己的编码习惯。”
老魏没有说话。
“三年前,我调试校准序列生成器的时候,在测试版本里加过一个非标准的偏移量。四个字节,3F 7A 2B 5C。用来标记测试版本号。没有技术意义,只是我自己能认出来。”
“你告诉过别人吗?”
“没有。”
“写进过文档吗?”
“没有。”
老魏慢慢站起来,走到控制室的窗户边。窗外,冷湖的夜空像一块被冻住的黑色玻璃,星星密集得让人头皮发麻。阵列天线的红色指示灯在戈壁滩上一闪一闪,像一列沉默的倒计时。
“林岸。”老魏背对着他说,“一个来自未来的信号,里面有你从没告诉过任何人的私人编码。这意味着什么?”
林岸没有回答。他知道答案,但他说不出口。因为那个答案意味着,发送这个信号的人,要么是他自己,要么是一个对他了解得比他自己还深的人。无论哪一种,都让他的后背发凉。
“我需要再查一遍。”林岸说,“从头查。”
老魏转过身来,脸上的皱纹在荧光灯下像一道道沟壑。“查什么?设备查过了,数据查过了,全都没有问题。林岸,你已经没有退路了。”
“还有软件。”林岸说,“校准序列生成器的固件。哈希值。版本历史。我还没查完。”
老魏看着他,叹了口气。那声叹息很长,像从很深的地方升上来的。他走回工位,拿起搪瓷杯,把里面剩下的液体一口喝完。
“我去把固件版本调出来。”老魏说,“但林岸,我告诉你,固件也不会给你答案。你心里清楚。”
林岸没有回答。他转过头,看着屏幕上那行十六进制字符。3F 7A 2B 5C。
他的手机在口袋里震动了一下。他掏出来看了一眼。林遥发来一条消息,只有四个字:
“爸爸,晚安。”
时间显示凌晨两点三十四分。西宁的医院里,女儿在手术前的夜晚给他发了一条晚安。他没有回复。他把手机翻过来扣在桌上,屏幕的光在暗下来的瞬间闪了一下,然后熄灭。
老魏从机柜里抽出一块板卡,那是校准序列发生器的固件模块。他把它插进读卡器,屏幕上的版本信息一行行跳出来。
“固件版本,2038年11月更新。哈希值,和当前运行版本一致。”老魏说,“没有异常。”
“把2038年更新前的版本也调出来。”林岸说。
“你要查版本历史?”
“查。”
老魏操作了几下,屏幕上出现了一串更早的版本记录。林岸逐个比对哈希值,一个接一个,从2038年往前追溯到2035年。他的眼睛在屏幕上快速移动,手指在键盘上不断敲击。
然后他停住了。
2038年11月的版本更新记录里,有一个微小的改动。改动内容没有写进更新日志,但哈希值变了。林岸调出那个版本的完整代码,在序列生成器的主循环里找到了一个非标准的偏移量。
3F 7A 2B 5C。
他的手指停在键盘上。这是他三年前写下的那个测试标记。它不应该出现在正式固件里。但它出现了。而且,回声信号中的那九个比特,与固件中的这个偏移量完全一致。
“固件里有我的编码。”林岸说,声音很轻。
老魏凑过来,看着屏幕上的代码。他沉默了很久,然后说了一句让林岸浑身发冷的话:
“这个版本的固件,是2038年11月更新的。更新人是你。但这个偏移量,在更新日志里没有任何记录。林岸,你什么时候把测试标记写进正式固件了?”
林岸摇了摇头。“我没有。我从来没有把测试标记写进正式版本。”
“但代码里明明有。”
“代码里有。”林岸重复了一遍。他盯着那行代码,感觉自己的大脑像被什么东西撬开了一条缝。他记得自己三年前写过这个标记,在测试版本里。他也记得自己后来清理了所有测试代码,正式版本里不应该有任何残留。
但代码就在这里。在他眼前。在2038年11月的正式固件更新里。
“有人改过代码。”林岸说。
“谁?你有权限,我也有权限。但更新日志里没有这条修改记录。”老魏说。
“修改日志可以被篡改。”
“那哈希值呢?”老魏指着屏幕,“固件的哈希值和版本记录里的哈希值完全一致。如果有人篡改了代码,他必须同时篡改哈希值。而哈希值的校验是独立的,存在DSO总部的服务器上。”
林岸没有说话。他调出DSO总部的哈希值校验接口,输入当前固件的版本号。几秒钟后,返回结果:
校验通过。当前固件版本与DSO总部记录的哈希值一致。
“数据篡改的假设,”林岸说,“正式排除。”
老魏把搪瓷杯重重地放在桌面上,发出“咚”的一声。控制室里的风扇嗡鸣声似乎被这个声音打断了一瞬间,然后又恢复了。
“林岸。”老魏的声音里带着一种林岸从未听过的疲惫,“我们查了硬件,正常。查了数据,正常。查了固件,正常。每一个环节都正常,但结果不可能。你告诉我,这是怎么回事?”
林岸没有回答。他坐在椅子上,盯着屏幕上的代码。3F 7A 2B 5C。那四个字节像四根钉子,把他钉在了某个他不愿意面对的事实上。
“我回宿舍了。”老魏说。他站起来,把棉袄的拉链拉到脖子下,“明天再查。如果还有明天。”
他走到门口,停了一下,没有回头。
“林岸,那九个比特的事,你先别对任何人说。尤其是沈岷。”
“为什么?”
“因为如果连你自己都不知道它为什么在那里,那知道它的人,可能比你想象的多。”
老魏走了。门在身后关上,声音很轻。控制室里只剩下林岸一个人。
他坐在那里,很久没有动。屏幕上的代码一行行排列着,像某种陌生的文字,记录着他不记得自己做过的事。他慢慢摘下眼镜,放在桌面上。镜片映着屏幕的光,像两片小小的方形月亮。
窗外,冷湖的夜风拍打观测站外墙,像有什么东西在轻轻敲门。
林岸重新打开回声信号的频谱图。他把那九个比特的片段单独提取出来,反复播放。波形在屏幕上滚动,那段非标准的编码序列在特定频段反复出现,像指纹一样清晰。
他想起自己三年前调试时的场景。那是深夜,也是在这个控制室,也是一个人。他在测试校准序列的自相关特性,需要快速识别某个测试版本,就随手在数据块里加了一个偏移量。3F 7A 2B 5C。四个字节,没有技术意义,只是一个记号。
他从未对任何人提过这个习惯。从未写进任何文档。从未在任何正式场合使用过。
但现在,它出现在一个来自未来的信号里。
他的手机又震动了一下。他翻过来看了一眼。还是林遥,这次是一条语音消息。他犹豫了一下,点开了。
女儿的声音从手机里传来,很轻,像怕吵醒隔壁病床的人:“爸爸,我睡不着。手术定在三天后。他们说成功率很高,但我知道这种话都是安慰人的。你能来看我吗?不用一直陪着,就来看看我就行。”
语音结束了。林岸把手机放回桌面。屏幕自动熄灭。控制室里只剩下他一个人,和那个来自未来的信号。
他调出信号的时间戳。2041年11月17日。三天后。林遥的手术日。
他的手指悬在键盘上方。那串编码还在屏幕上,3F 7A 2B 5C。他想不起自己是什么时候把测试标记写进正式固件的。他想不起那个更新日志里没有记录的修改是怎么发生的。他唯一能确定的,是他从来没有向任何人提过这个习惯。
但现在,它在一个来自未来的信号里。被精确复现。
林岸盯着那串编码,想起自己从未对任何人提过这个习惯。窗外,冷湖的夜风还在拍打外墙,像有什么东西在轻轻敲门。