$$ 01 $$
自從添加了‘循環(huán)冗余校驗’后,牛郎織女信件內(nèi)容的準(zhǔn)確度極大提高。
但是最近,牛郎突然發(fā)現(xiàn),信件中部分句子,還是有不少7次都沒有正確傳輸?shù)摹?p> “難道是我對傳輸穩(wěn)定性的預(yù)估有誤?”牛郎暗自想,“但是這不可能啊。”
忽然,牛郎靈機一動:“不會是有人像篡改內(nèi)容,但是尚不知校驗規(guī)則,正在探索嘗試吧?”
“這就危險了,‘循環(huán)冗余校驗’難度不大,破解只是時間問題。”
“既然如此,還需要一種識別數(shù)據(jù)篡改的方式。”
·
接下來的幾天,牛郎沒有與織女聯(lián)系。
牛郎心里清楚,每次聯(lián)系都是給對方試探的機會,自己沒有想好新的校驗規(guī)則之前,需要盡量減少與織女的溝通。
“其實,也不是很難,只要找到一種方式,讓全文所有內(nèi)容參與計算,得出一個校驗值就好了?!迸@勺匝宰哉Z。
“但是,全文內(nèi)容太多了,如果還是之前的筆畫方式的話,恐怕誤差會比較大?!?p> “同時,還要考慮安全性,算法總是會暴露的,如何在王母知道了算法的情況下,也盡量保證數(shù)據(jù)安全?!?p> ·
看來,需要考慮的事情不少,牛郎想各個擊破。
“首先,是算法上的問題。本質(zhì)上還是筆畫,只是按原來‘循環(huán)冗余校驗’的方式,王母想要偽造太簡單?!?p> “只要替換一句筆畫相同的句子,就可以繞過校驗了。這很危險,必須讓每個字的筆畫都參與運算,都會影響結(jié)果?!?p> ·
“如果兩句話字數(shù)、每個字的筆畫數(shù)都一樣,但是卻要表達不同的意思,這很難。這就是新的校驗法的核心思想?!?p> ·
----
$$ 02 $$
那么問題來了,具體應(yīng)該怎么辦呢?
牛郎想,不如先從簡單地方式來思考,先把每個字的筆畫,都寫出來。
原本是一封全是文字的信件,每個文字對應(yīng)的位置替換為筆畫數(shù),瞬間變成了一張數(shù)字表。
“這個數(shù)字表看起來很條理,不如把每一列都加起來試試。只是每一句話有長有短,最后的結(jié)果取決于最長的一句,這樣不太好?!?p> ·
牛郎重新思考了一下,信件中,最長的句子是80字,以后可能會有更長的句子,這樣會失控的。
牛郎拿起一張新的紙,按照每行32個字的規(guī)則,將整篇信件抄寫了一遍。
“現(xiàn)在好了,句子再長,由于32個字就會換行,再也不會出現(xiàn)校驗值過長的問題了?!?p> ·
牛郎重新在每個字的位置標(biāo)好筆畫數(shù)目,標(biāo)點符號作為一個字,但筆畫記為0畫。
如此按照列加起來,牛郎得到了32個非常大的數(shù)字。
“從一定程度上講,這32個數(shù)字,確實可以校驗一篇內(nèi)容的完整性。但這樣,還是有點冗長了?!?p> 這時候,牛郎又想起了那個魔數(shù)7,“不如把每個數(shù)字再除以7,取余數(shù),這樣就是32個一位數(shù)了,應(yīng)該就方便多了?!?p> ·
牛郎寫下來這32個數(shù)字,還是感覺缺少了點什么??偢杏X,好像是過于死板了,缺少一種靈動感。
突然,牛郎一拍腦門,“明白了!數(shù)字還是看起來太亂了,32位數(shù)字更是讓人一眼就看暈了?!?p> “這樣的話,我用12的余數(shù),用12地支表示結(jié)果,每8個一組,應(yīng)該會好很多了。”
于是,牛郎重新計算校驗值,然后在下方寫下了:
“子丑寅卯……”
·
----
$$ 03 $$
牛郎看著一列一列計算出來的校驗值,如此大量的文字,竟然最后的結(jié)果只有這么一串文字。
取個什么名字好呢?將信件分散為筆畫,然后按列來計算,不如就叫做“散列算法”吧。
防止篡改的方法確定了,那么,如何避免計算出來的校驗值被修改呢?
牛郎想了想,既然如此,就把這個校驗值放在信件的第一行吧。
先發(fā)出去校驗值,即使被攔截,由于對方不知道信件的整體內(nèi)容,也是無法進行修改的。
·
牛郎趕緊給織女寫了一封信,描述了這個方法,并約定以后的通信,都用這種方式進行校驗。
牛郎很開心,自己終于解決了一個大問題。
第二天,牛郎收到了織女的回信,內(nèi)容很簡單:“通篇偽造怎么辦?”
·
牛郎一時語塞,想想也是,自己解決了局部篡改問題,只修改部分內(nèi)容可以被快速發(fā)現(xiàn)。
但是,王母知道了該機制后,確實無法改一部分,但他們直接把一整篇全偽造,我這還真沒辦法。
甚至,說的極端一點,現(xiàn)在我看到這封信,還真不能肯定,到底是織女寫的還是王母寫的。
這個問題,確實是有點尷尬的。
·
“看來,需要混入一些只有我和織女才知道的東西,才能保證對方身份的安全性。”牛郎想。
“比如,將我和織女初次見面的時間算進去?”
接著,牛郎又否定了自己的想法:“現(xiàn)在僅僅基于筆畫,方法過于簡單,多次通信后,王母可能反推出這個時間?!?p> “看來,要想辦法強化這個算法的不可逆性質(zhì)了。”
·
----
$$ 04 $$
牛郎來到桌前,在紙上寫出32位的校驗值,然后又按照“年月日”的格式,寫出了8位時間。
也就是說,牛郎需要將原始校驗值與見面日期結(jié)合,生成一個安全的校驗值,同時還要保證,見面日期不可被反推出來。
“要保證見面日期的安全性,這還真是有點難度的?!迸@勺匝宰哉Z道,“因為安全校驗值是明文傳輸?shù)?,而原始校驗值則可以通過內(nèi)容計算出來?!?p> ·
牛郎想著想著,突然手中的筆不小心掉了下來,剛好涂掉了原始校驗值的最后兩位。
牛郎撿起筆,放到桌上,看著紙上留下的痕跡,靈機一動:
“對了,只要減少見面日期影響的位數(shù),就很難反推了。如果見面日志只影響這最后兩位,神仙也不能能基于它推出原來8位的日期?!?p> ·
牛郎再次拿起筆,在紙上記下了處理思路:“取原始校驗值的最后兩位,與見面日期拼成10位,與剩余的30位原始校驗值計算出2位尾數(shù),拼回去作為安全校驗值?!?p> 那么問題來了,具體要怎么算呢?這沒什么難點,在沒有前人鋪墊的情況下,我說啥不就是啥么?
牛郎重新看了一眼信件,將被涂掉的最后兩位重新寫到紙上。
“午戌。午是第7位,戌是第11位。那第二行,從第5位開始寫這10位,第三行,從第11位開始寫這10位內(nèi)容?!?p> 牛郎寫好后,將這三列再次按列加起來,得到30位內(nèi)容。
·
現(xiàn)在,要想辦法將這30位變成2位數(shù),并且要盡量有選擇地丟棄一些信息,避免數(shù)據(jù)被反推。
牛郎很隨性地想了一個辦法:“第一位,將3的倍數(shù)位的內(nèi)容加起來,取除以7的余數(shù)。”
“第二位,將4的倍數(shù)位的內(nèi)容,加起來,也取7的余數(shù)。這樣,由于篩選,見面日期總是部分參與運算,從而保證安全性。”
牛郎算出了結(jié)果,第一位是2,第二位是4,牛郎就在原始校驗值的30位后面,補充上了這兩位:“2對應(yīng)‘乙’,4對應(yīng)‘丁’,這就完整了?!?p>