×

为什么1999年程序员全在熬夜?一个 “省空间” 的设计,差点拖垮全球系统!

hqy hqy 发表于2025-10-25 01:22:27 浏览7 评论0

抢沙发发表评论

1999年12月31日的夜晚,很多人在等新年钟声,全世界都沉浸在迎接千禧年的喜悦中。

但有一群人没心思跨年,他们还在加班,从几个月前,他们就守在电脑前,眼睛时刻盯着屏幕上的代码,这群人就是程序员

让他们熬夜加班的,不是普通的加班赶项目,是一个会随着2000年到来而造成不可估量的损失的漏洞。

这个漏洞有个名字,叫千年虫Bug。

没人能想到,这个漏洞的源头,只是早期程序员为了“省空间”做的一个设计,就是这个设计,差点拖垮全球的计算机系统。

从银行的账户计算,到军队的武器系统,从家里的燃气表,到天上的卫星导航,都可能因为这个漏洞停摆。

因此,1999年的跨年夜,成了全球程序员的“战场”,他们要在时钟跳到2000年0点前,把这个隐藏了半个世纪的隐患,彻底堵住。

01 千年虫Bug

千年虫Bug,国际上习惯地简称Y2K(Y是year的首字母,2K是2000的意思),它并非病毒,而是计算机程序处理日期时的逻辑漏洞。

图片

20世纪50年代,计算机的存储还是采用的磁芯存储器(如上图),它的原理是,磁芯存储器通过XY导线交叉寻址,写入时交叉处电流叠加超阈值磁化存 0/1,读出时同电流叠加,依磁芯翻转与否在斜向读出线产生感应电流判状态,因破坏性读出需立即重写原数据。

但是,每字节存储成本达数十美元,内存与硬盘资源极度稀缺。

为压缩存储,程序员采用6位BCD码(二进制编码十进制)表示日期:前两位存年份、中间两位存月份、最后两位存日期,默认年份前缀为“19”。

还是举个例子直观一些,例如,1987年3月15日,就可以记为“870315”,该设计在COBOL语言中被标准化,而这种语言当时垄断大型机核心系统开发,也是因为如此,这个漏洞随才会被“普及”。

图片

?格蕾丝·赫柏(1906年12月9日-1992年1月1日)

而提出该设计的计算机科学家格雷斯・霍普(美国计算机科学家、海军少将),同时也是“Bug”术语的首创者(1947年因飞蛾卡电路板命名故障)。

但她未预见的是,短期存储优化会埋下长期隐患。

早在1958年,美国程序员鲍勃・贝默就指出,两位年份字段会在2000年触发“00→1900”误判,这会导致日期计算溢出。

但当时2000年尚远,IBM评估修改需耗资数百万美元(相当于两座中型工厂造价),这个预警未被重视。

他们没有想到的是,千年虫还伴随两个衍生漏洞。

一个是部分系统未将2000年识别为闰年,会从2月28日直接跳至3月1日,造成日期断层;

二是老系统用“99/99”标记文件结束,1999年9月9日可能触发误删逻辑。

就这样,一直到1990年,美国某保险公司保单系统将2000年到期保单标记为“1900年失效”,漏洞才首次显现。

然而,真正被重视起来的,还是要到1997年,这一年,信息界正式拉响警报,全球开始正视这一隐藏半个世纪的风险。

02 千年虫Bug有什么影响?

千年虫的影响首先体现在国防军事领域,核心风险是时间同步异常导致的指令误判。

时间有多重要,不用我多说,大家各自有概念,而对于军事领域,可能不是那么清晰,但是军用时间总该听说过吧?

这个时间用来核弹发射,导弹发射,系统更新维护等。

1996年,美国国防部就做了一个测试,结果表明,120余个军事程序未修复时,2000年1月1日会触发“导弹误判”,“爱国者”防空系统的目标追踪模块,因日期字段溢出,将50公里外友军战机误判为“1900年入侵的敌方导弹”,并启动拦截流程。

这对于美军和他的友军来说,无疑是巨大损失。

不仅如此,美国海军“宙斯盾”驱逐舰的指挥系统更严峻。

它的时间跳转为1900年后,敌我识别(IFF)系统的时间戳验证失效,无法区分己方舰艇信号,还有舰载导弹的发射授权逻辑因“年份超期”锁死,需重新编译固件才能解锁。

好家伙,这要是遇到变故,该如何了得。

美国有问题,那俄罗斯也不例外,它的战略预警系统同样受困于这个问题。

俄罗斯的早期雷达数据处理程序是用8位寄存器存年份,2000年后会触发寄存器溢出,可能会将西方正常的军事演习,误判为核打击,从而引发冲突......

而这些都是开胃菜,那要是核弹呢?大家自行脑补吧。

除军事领域外,经济与金融领域同样危机四伏,2000 年临近之时,各机构均提前开展了“灾难”测试。

老公,男朋友偿还房贷的银行,它的系统首当其冲面临风险。由于日期计算错误,可能引发账务紊乱。

以美国大通银行的测试为例,系统会将1999年存入的1年期定期存款,错误地按照“1900-1999年存期”计算利息,致使每个账户平均多计算1200美元利息,相当于多算了8年利息。

倘若涉及50万笔账户,这将造成巨大损失,甚至可能引发挤兑风险。

也就是说,即便你躺平着,账户也可能无端多出数千元。

还有期货交易所,它的衍生品结算系统更关键。

1999年12月搞模拟跨世纪交易的时候,芝加哥交易所也发现了BUG。3个利率期货合约的结算日期算错,为啥呢?

原来是系统把2000年1月1日当成1900年了,这可不得了,直接让合约价值偏差了20亿美元。 

还有涉及民生领域的电力系统,它的风险集中在嵌入式控制模块。

美国夏威夷电力公司测试显示,输入“00”年份后,变电站的SCADA(数据采集与监控)系统因日期验证失败,自动切断变压器供电,导致局部电网电压波动±15%。

法国电力公司则发现23个变电站的温度监控程序,误判“设备已运行100年”,触发保护性停机,影响30万居民用电。

说了电力系统,就要提一下交通领域。

美国通用汽车在1995-1999年生产了100万辆汽车,这些汽车的发动机ECU(电子控制单元)的EEPROM中,年份存储字段仅8位(含两位年份),如此会导致2000年后会判定“车辆超期报废”,直接锁死发动机。

那要是核电站呢?

美国三里岛核电站的模拟测试更严峻,未修复的反应堆冷却系统监控程序,会将2000年的冷却剂循环时间误判为“1900年至今”,触发紧急停机,影响区域供电。

一个小小的时间问题会在各行各业引发各种各样的问题,接下来我们来看大家都是怎么应对的。

03 美国军方是怎么应对的?

美国军方将千年虫应对列为“最高国防优先级”,1995年启动项目,累计投入12亿美元(占当年国防部IT预算18%)。

首先建立层级化应对体系:国防部成立“千年虫专项小组”,由副部长牵头,整合陆、海、空三军IT主管与民间专家,每周向总统提交进度报告。

1998年克林顿签发总统令,成立“2000年计算机转换委员会”,授权军方调用民用IT资源。

修复遵循“优先级排序模型”:一级为核设施、战略武器系统(如洲际导弹、核潜艇导航);二级为作战装备系统(如战机雷达、舰艇指挥);三级为后勤与行政系统。

光1996年首轮排查就识别出3.2万个需修复得系统,1.1万个一级系统要求1998年底前完成。

还有那些核设施与战略武器系统的修复,这就复杂了,它们得核心是逆向工程。

美军14个核武器库的控制程序、500枚“民兵-3”洲际导弹的制导系统,均采用1970年代前的COBOL与汇编语言开发,技术文档缺失,需邀请70余名退休程序员(最年长78岁)参与逆向。

这些白发苍苍得老人们需要通过分析机器码,定位日期处理模块,修改DATE-OF-INTEGER与INTEGER-OF-DATE函数,从而来确保跨世纪转换正确。

但是呢,当年很多会用COBOL语言得程序员,如今都退休,想要修复这么多,这大规模得系统,人数太少了。

为解决COBOL程序员短缺,美军与印度塔塔咨询、Infosys签订合同,引进1.2万名技术人员。

这些人员需通过3个月军事安全培训,掌握保密条例与军用COBOL方言,主要负责后勤系统修复(如物资调度、人员考勤),核心武器系统修复仍由美军程序员主导。

到了1999年12月31日跨年夜,美军进入“DEFCON3”应急状态。

所有军事基地的技术人员24小时值守,每个关键系统配备双岗;核设施监控数据实时传输至五角大楼“国家军事指挥中心”,每小时生成状态报告;与北约盟友建立“实时信息共享链路”,避免故障误判。

最终,美军所有一级系统顺利跨世纪,仅处理17起轻微异常(如行政系统日期显示错误),均在10分钟内修复。

04 我国是怎么应对的?

1998年,我国成立 “计算机2000年问题协调小组”,将银行、电力、交通、医疗列为重点领域,建立 “月度通报 + 季度检查” 机制,统筹推动全行业整改。

在这一部署下,各领域迅速启动针对性应对工作。其中银行系统的核心举措集中在代码审计与压力测试。

中国人民银行要求各银行对账户管理、资金结算等核心业务系统,开展全量 COBOL 代码审计。

通过 MicroFocusCOBOLAnalyzer 等静态代码分析工具定位日期字段,累计修复问题代码超50万行。

广东银联的改造尤为典型,1998年4月起,50人技术团队对银联网络系统进行改造,修改1200余处日期处理逻辑并于9月完成上线。

1999年12月,团队又开展3次24小时高并发测试,模拟10万笔 / 秒跨行交易验证跨世纪稳定性,确保2850台ATM与1172台POS 正常运行。

为进一步降低跨年夜系统压力,1999年银行将结算日期提前至12月30 日,各网点还配备手工账本与算盘,制定 “系统故障时手工办理业务” 的应急预案。

除银行系统外,民航系统的应对重点放在主机升级与异地备份。

中国航信自1998年1月起,将离港系统数据库迁移至支持四位年份的优利 2200/644 主机,同时将订座系统操作系统升级至45R2版本,并修复 TOCED、RCVRY等模块的日期判断逻辑。

为保障数据安全,航信还建成北京东四机房与上海备份机房,通过同步软件实现核心数据实时备份,确保单点故障不影响全局运行。

电力系统的整改则聚焦嵌入式控制模块。

国家电力公司组织各省电力局,对1.2万个发电、输电系统进行全面排查,要求3000个关键变电站的SCADA系统在1999年10月底前完成修复。

同时,每个电厂配备应急发电机(满油可运行8小时,确保断电后临时供电)与续航15分钟的UPS系统,并建立 “跨区域电力调度联动机制”,保障一处停电时可从邻近区域调配电力。

医疗领域的应对策略侧重设备检测与手工预案。

卫生部要求各级医院对监护仪、麻醉机等设备开展 “时间跳变测试”,手动将时间调至1999年12月31日23:59,排查潜在问题。

对无法修复的老旧设备提前更换。

同时,医院加强医护人员手工操作培训,比如人工计算输液速度、监测心率;北京、上海的三甲医院还在跨年夜安排设备科人员驻守,确保设备故障能在 10分钟内响应处置。

通过各领域的周密部署与高效执行,我国平稳度过了 1999 年到 2000 年的跨世纪转换。

05 全球有多大的损失?

千年虫爆发前,专家预测未修复的全球经济损失可达3000亿-6000亿美元(部分机构预测超1.6万亿美元,占当时全球GDP5%)。

图片

为规避风险,全球投入超2000亿美元用于修复:美国800亿美元(联邦政府100亿、私营企业700亿),欧洲600亿美元,亚洲400亿美元,平均修改1行商业系统代码成本1美元,军事系统达10-50美元。

实际损失集中在准备不足的区域与领域。

2000年1月1日,西非冈比亚的财政部、税局、海关系统全面瘫痪。

因为他们仅完成了30%关键系统修复,政府被迫宣布当天为非工作日,财政收入统计延误1周,进出口贸易停滞,直接损失500万美元。

瑞典10万网上银行客户无法登录,因银行采用的“时间窗口算法”(1920-2020)未处理“00→2000”逻辑,将账户误判为“1900年休眠账户”冻结,间接损失200万美元,涉事银行被罚款50万美元。

香港7-11便利店的信用卡支付系统故障更典型。

虽然投入了880万美元进行修复,但测试未覆盖“2001年”远期日期,导致系统将2001年误判为1901年,拒绝信用卡交易,当天现金销售额增30%但整体营收损失50万港元,次日才通过远程补丁修复。

神奇的是,也有美国的。

美国120家社区医院出现医疗仪器故障。小型医院因资金有限未修复所有设备,部分心脏监护仪显示“设备使用超100年”后停机,医护人员需手工监测,额外产生20万美元人力成本。

图片

实际上,事后的不完全统计,全球直接经济损失约300亿美元,远低于预期。

这得益于那些加班加点,埋头进行提前修复的程序员们,向他们致敬!

06 总结

千年虫本质是“技术债”的典型案例。就为节省存储,却忽视长期兼容性,在半个世纪后演变为全球危机。

但这次危机,也为人类带来了一些经验。

2000年来临之前,全球程序员熬夜修复,是人类首次大规模技术协作。

美国军方的逆向工程与优先级模型、我国的静态代码审计与异地备份,形成了“预警-排查-修复-测试-应急”的完整技术风险应对框架,为后续全球性IT危机提供范本。

对于计算机行业来说,这场危机后,日期存储普遍采用四位年份,部分系统预留五位字段预防“万年虫”

软件测试新增“时间边界测试”(如跨世纪、闰年),COBOL等语言也推出DATE-TIME扩展模块,强化日期处理容错性。

而与千年虫同源的2038年问题(32位Unix时间戳溢出,1970+2^31秒=2038年),目前正借鉴千年虫经验,通过升级64位系统、修改时间存储格式提前化解。

那你觉得,如今的手机支付、高铁调度、航空航天中的日期验证,还有出现类似的问题吗?


打赏

本文链接:https://kinber.cn/post/5760.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客