謝作如 浙江省溫州中學(xué)
隱寫術(shù)(steganography)一詞來源于希臘詞匯stegons和graphia,意即“隱藏”和“書寫”,即把某些特殊信息隱藏于正常載體之中,從而實(shí)現(xiàn)掩蓋特殊信息存在的事實(shí),不易引起敵方的懷疑。信息隱藏的發(fā)展很大程度上得益于戰(zhàn)爭中隱蔽通信的需要。我國古代有文字可考的最早的信息隱藏見于《六韜》中對“陰符”的記載。其辦法是先制造形制、花紋不同的兵符,每一種表示一種固定的含義。這種含義須事先約定好,只有當(dāng)事人可以理解,即使被敵方截獲,他們也不會(huì)知道其中的含義。
在教學(xué)《數(shù)據(jù)與計(jì)算》(高中信息技術(shù)必修模塊1)中關(guān)于信息加密的時(shí)候,筆者給學(xué)生介紹了密碼的加密解密技術(shù),并在網(wǎng)頁上演示了圖片隱寫術(shù)的做法,不想引起了學(xué)生極大的學(xué)習(xí)興趣。于是筆者就產(chǎn)生了想法:用Python的PIL庫來實(shí)現(xiàn)圖片隱寫術(shù),從而讓學(xué)生深入理解信息的編碼原理和規(guī)則。
圖片是由一個(gè)個(gè)像素組成的。在常見的彩色圖片中,每一個(gè)像素都由三組數(shù)字表示,代表紅色(r)、綠色(g)、藍(lán)色(b)三種顏色。其中,每一種顏色的深淺一般由0~255之間的數(shù)字表示,即一個(gè)字節(jié)(8個(gè)Bit),因而在Windows中查看這類圖片的屬性,會(huì)看到其位深度為“32”,如圖1所示。
圖1
既然每一個(gè)像素的單種顏色是采用8位來存儲(chǔ),那么如果改變其最低位的值,對整個(gè)圖片來說,其視覺效果變化就很小,通過肉眼是看不出來的,如當(dāng)一組顏色白色(255,255,255),變?yōu)椋?54,255,255)時(shí),幾乎沒有區(qū)別,因?yàn)椴罹鄡H僅是1/255。如下頁圖2所示的兩張小狗,其中一張加入了隱藏的信息,但是幾乎看不出任何區(qū)別。
那么,對于一張大小為800*600的圖片來說,就有800*600*3個(gè)位的空間可用于隱藏信息。只要將待隱藏的文字信息轉(zhuǎn)換為二進(jìn)制,再將每個(gè)二進(jìn)制碼存儲(chǔ)在圖片的像素中,就達(dá)到了隱藏信息的目的。
Python的PIL庫可以讀取圖片的信息,包括所有的像素顏色。這就需要編寫一段代碼,逐步完成如下工作:
①獲取原圖片的所有像素,將每一個(gè)像素顏色的數(shù)字最低位變?yōu)椤?”;
②將待隱藏信息轉(zhuǎn)換為二進(jìn)制字符串,如果位數(shù)不夠8個(gè)時(shí),在最高位補(bǔ)0;
③將二進(jìn)制的待隱藏信息依次與圖片中每個(gè)像素的r、g、b顏色數(shù)字進(jìn)行相加,形成新的圖片。
為了方便調(diào)用,筆者編寫了三個(gè)函數(shù),分別實(shí)現(xiàn)這些功能,函數(shù)代碼如圖3、圖4、圖5所示。
準(zhǔn)備工作已經(jīng)完成,接下來要隱藏信息就調(diào)用“encodeDataInImage”函數(shù)。為了方便理解,筆者在代碼中輸出了一些特定的信息,如加密后的二進(jìn)制代碼和加密后的像素,具體效果如下頁圖6所示。
圖6
在運(yùn)行代碼后,目錄中將多出一張名稱為“加密.png”的圖片。這就是加密過的圖片。用肉眼你肯定看不出有任何變化,因?yàn)閮H僅改動(dòng)了17個(gè)像素,而且這17個(gè)像素的變化又非常小。需要注意的是,選擇的“原始.png”圖片不支持“透明”,即沒有透明度的信息,支持“透明”的PNG文件的每一個(gè)像素是4組數(shù)字。
在得到加密后的圖片后,下一步的工作就是解密,以驗(yàn)證這一做法是否可行。需要完成如下工作:獲取圖片的所有像素,將像素值的最低位取出并拼接為一個(gè)二進(jìn)制字符串。需要注意的是,我們只要把“有效”的信息取出即可,如果二進(jìn)制字符串出現(xiàn)連續(xù)的16個(gè)以上的0,說明后面就不存在有效信息了。
獲取存儲(chǔ)的信息的二進(jìn)制值,按每8位為一組,將上述二進(jìn)制轉(zhuǎn)換為十進(jìn)制形式,再轉(zhuǎn)換為Bytes類型,用decode將十進(jìn)制轉(zhuǎn)為字符并存儲(chǔ)到字符串中。
同樣為了方便調(diào)用,筆者分別編寫了兩個(gè)函數(shù)來實(shí)現(xiàn)以上功能(如圖7、圖8)。
分別執(zhí)行decodeImage和binaryToString兩個(gè)函數(shù),即可輸出解密后的信息,如圖9所示。
圖9
實(shí)現(xiàn)圖片隱寫術(shù)的方法很多。本案例僅僅使用了一個(gè)像素單色數(shù)據(jù)的最低位,如果要隱藏更多的信息,甚至可以利用這個(gè)字節(jié)的后四位。當(dāng)然,如果使用了后四位來加密,那么用于加密的原始圖片的背景顏色最好比較復(fù)雜,這樣加密后就不容易被發(fā)現(xiàn),不能選擇存在大片相同顏色的圖片,如藍(lán)天白云的風(fēng)景圖。此外,用于加密的原始圖片可以是任意格式,但是保存后的圖片需要用PNG或者BMP格式,即未壓縮格式,不然加密后的圖片一旦被壓縮,信息就被破壞了。
計(jì)算機(jī)的發(fā)明和密碼破譯有著千絲萬縷的關(guān)系,信息的編碼又是加密和解密的基礎(chǔ)。本案例涉及了字符編碼、圖片編碼、進(jìn)制轉(zhuǎn)換、Python編程等方面的知識(shí),將知識(shí)學(xué)習(xí)融入到有意義的探究過程之中,值得作為一個(gè)信息技術(shù)實(shí)驗(yàn)讓學(xué)生在課堂上研究。本案例代碼還有很多細(xì)節(jié)可以讓學(xué)生探究,如為什么出現(xiàn)16個(gè)0就說明后面的信息是無效的、為什么加密時(shí)二進(jìn)制字符串(binary)的長度要按照3的倍數(shù)進(jìn)行補(bǔ)足等。
此外,信息的加密解密是一個(gè)很不錯(cuò)的信息技術(shù)學(xué)習(xí)主題,完全可以作為一個(gè)項(xiàng)目讓學(xué)生深入研究。有趣的是,筆者的學(xué)生在研究完這個(gè)案例后,就開始研究如何在聲音和視頻中隱藏信息。雖然他們可能會(huì)遇到很多困難,但這一探究過程對他們學(xué)習(xí)信息技術(shù)有著非常重要的意義。