陳凱


胡亂打字通關游戲
一些信息技術教材在提到“信息”的概念時,會引用香農的觀點:“信息是能夠用來消除不確定性的東西?!边@里的“不確定性”其實指的是隨機不確定性。為什么所謂的信息和隨機不確定性有關呢?這個問題可不簡單,并不是三言兩語就能夠說明白的。為了對所謂的隨機不確定性有直觀的感受,不妨先來看一個簡單的通關游戲。游戲是用Python語言寫的,運行界面如圖1所示。
游戲提示說,輸入合適的口令,才能通關到下一步,可是口令是什么呢?這時候只有隨便敲打鍵盤看自己運氣了。唯一的要求是輸入的字符數量要多于50個。至于輸入的字符是什么,輸入的字符順序怎樣,輸入的字符是否重復,這些都無所謂。然而,也許玩家無論怎樣輸入字符,都無法過關,如圖2所示。
再來一次,可還是不行,如圖3所示。
然而,筆者“隨便”敲打輸入一大串字符,就奇跡般地過關了,如圖4所示。
多試幾次,結果也是這樣。筆者輸入的字符看似完全沒有規律,但每次都能順利過關。實際上,這些字符確實是胡亂敲打輸入的,但在敲打輸入時,有一個非常隱蔽的訣竅。仔細觀察,我們可以發現,輸入字符后代碼會反饋一串帶小數點的數字。玩家前兩次輸入后,得到的數字大約是3.14和2.42,但筆者輸入字符后,這串數字是3.07。在Python程序代碼中,存在著一句判斷語句,當這個數字大于2.95、小于3.1的時候,就能完成游戲通關。為了便于玩家通關,代碼里將數字顯示在了屏幕上,如果不顯示這個數字,要通關就更困難了。
這個數字究竟是怎么來的呢?它代表的就是根據玩家所輸入的一大串字符所計算出來的隨機不確定性。數字越大,隨機不確定性也就越大,數字越小,隨機不確定性也就越小。為了能夠通關,我們就必須把握好所輸入的字符的隨機不確定性??墒?,怎么把握輸入字符的隨機不確定性呢?再一次觀察筆者輸入的字符,可以發現總共有十種不同的字母,其中九種字符出現的概率大致是相同的,而字符“g”出現的概率遠小于其他字符。當然,出現概率被降低的字母不一定是“g”,再一次玩游戲時,也可以降低其他字母的概率,若是不公開說明,旁人是很難發現其中蹊蹺的。那么,輸入的每一串字符的隨機不確定性是怎么計算出來的呢,且看完整的Python代碼,如圖5所示。
代碼中用到了Counter類,它的作用是跟蹤每個字符出現的次數,lns變量存儲的是整個字符串的長度,count是某個字符在整個字符串中總共出現的次數。代碼中最關鍵的一段數學公式,就是count/ lns*math.log(lns/count,2)。這段公式到底起什么作用呢?我們可以通過輸入不同的字符來試試看。例如,輸入字符串aaaa,則count為4,lns也是4,count除以lns,或lns除以count,都得到1,然后,對于數字1,取以2為底的對數,這其實就是問2的幾次方是1,結果是0。代碼中for循環結構所做的工作,是對出現的不同的字符進行上述運算后,再將結果累加起來,不過因為字符串aaaa只有一種字母,所以等于沒有做加法,結果自然還是0。數字0意味著玩家輸入的字符串中的每個字母非常有規律,隨機不確定性低到了極點。
如果輸入的是字符串aabb,則對于第一種字母a,count為2,lns為4,count除以lns得到0.5,lns除以count就得到2,然后,對于數字2,取以2為底的對數,這其實就是問2的幾次方是2,結果是1。最后,循環語句實際執行的操作就是0.5*1+0.5*1,結果為1。這就能看出,字符串aabb與字符串aaaa相比,輸入的每個字母的隨機不確定性要高一些。
湊數通關法及其背后的深意
假設事先知道,當輸入字符串的隨機不確定性值在2.95和3.1之間就能通關。那么,怎么用一堆貌似胡亂輸入的字符串湊出3.0這個數字呢?最簡單的辦法就是先湊出3/8,然后將3/8算上它自己累加8次,湊數時需要一些逆向的思維:
3/24代表什么呢?其實就是說,如果輸入的字符串長度是24,那么每個字符需要出現3次。不過根據剛才游戲的要求,規定玩家輸入的字符數量要多于50,那么只要分子分母各乘以3就可以了,也就是說,輸入72個字符,每個字符出現9次,這就意味著字符串中總共會出現8種不同的字符,每個重復9次即可。有了這個尺度,再玩游戲,那絕對能通關了吧,如圖6所示。
若要湊出隨機不確定性值為4,那也很容易,比如可以將2/32* math.log(32/2,2)算上自己加上16次,2/32分子分母各乘以2,得到4/64,也就是說,玩家輸入16種不同的字符,每個字符重復4次即可。其實這里已經可以看出明顯的規律,若輸入的字符串字符概率均等,當字符種類是2時,則隨機不確定性值是1;當字符種類是4時,則隨機不確定性值是2;當字符種類是8時,則隨機不確定性值是3;當字符種類是16時,則隨機不確定性值是4。只要字符出現概率均等,那么隨機不確定性值的計算就可以用以2為底的對數函數來獲得。這里的隨機不確定性值,實際上就是描述信息混亂程度的信息熵,它的單位是比特。信息熵和數據存儲容量,其實是不同視角之下的同一件事。
信息熵在線玩
本文提供的小程序可以用來測試簡短字符串的信息熵,如果要檢測較大文件的信息熵,就要增加許多代碼,好在網絡上提供了在線測試文件信息熵的工具,不僅能計算信息熵的值,還能夠用直觀的圖表顯示出文件中不同字符所出現的頻率,這個在線工具的地址是https://servertest.online/entropy。例如,可借用此在線工具分析某張照片的原始BMP格式(如上頁圖7)和轉成JPG格式后,信息熵值及信息分布頻率的不同,如上頁圖8和圖9。
兩張圖的信息熵值差異不大,為14多一些,但JPG圖片容量大小只有原始圖片的一半,可以發現,JPG圖片中,不同信息(字符)在空間中是均勻分布的。如果將原始BMP格式圖片轉化成16色位圖,雖然最終文件容量和JPG文件差不多,但圖像質量卻大受影響,這從信息熵值的變化以及信息頻率分布圖中就可以看出端倪,如圖10和圖11。
16色位圖的信息熵只有4多一些,從頻率分布圖看,某些字符被大量使用,但圖中也存在著大塊空白,差不多容量相同的文件,16色位圖中每個字符所可能表達的信息的多樣性,要遠小于JPG格式的圖片。從這個例子也可以看出,信息熵值對應著文件中每個符號可能攜帶的信息量。
大家可以利用這個在線工具,分析比對不同文件壓縮前后的信息熵和信息頻率分布的情況,針對不同教學目標,組織多樣的教學實踐活動。直觀互動的體驗,再結合數字計算,有助于提高對信息熵這個抽象概念的理解。