原文地址:平安夜的祝福
本來想等文章收錄之後再發表到這裏的,然而一直沒有等到,不知道爲什麼;寫於2016年12月25日。
昨天是平安夜,收到了好多祝福,還有班長大大的Apple(!phone)
BUT,我能直接看懂祝福的內容,這樣好沒有挑戰性哦。
想把自己的祝福隱藏在什麼裏面,然後發給想要告訴的人,畢竟我是計算機系的學生啦!
可是放在哪裏好呢?
加密成字串
可以直接被破譯的有base64,可是看起來好簡單
自己寫的話在大一就已經做過了,不想重複
其他的,或許很難破解咯
- 隱藏在圖片裏面
- 以前沒有做過的事情,可以嘗試
- 會讓對方想到文字就在圖片裏面的陷阱
接下來就給大家說兩種簡單的隱寫方法吧
0x00 圖種
因爲一張正常的jpg圖片是以FF D9
作爲結束標誌的,而圖片查看器在打開圖片的時候會忽略結束符之後的內容,因此,我們可以在圖片的結束符之後追加我們自己想要隱藏的信息。
我們需要製作一個zip文件,放入想要隱藏的內容,再找一張jpg格式的圖片,以二進制方式把兩個文件首尾相接即可。
Windows :copy /b photo.jpg+file.zip output.jpg
Linux :cat file.zip >> photo.jpg
缺點是這樣的方式隱藏的信息很容易被發現,因爲只需要看看jpg圖片的FF D9
之後有沒有內容便可知道真相。
0x01 平安夜的驚喜
public.png
key.png
key.png是原圖,我在它裏面添加了自己想要說的話,然後public.png是處理之後的圖片,你能在其中找到答案麼?
還有的就是,我把它發給了我最最最最最要好的朋友[害羞]:
>> 吶,這兩個 [可愛]
<< 這兩個有什麼區別 [小糾結]
>> 不告訴你
<< [doge]
>> 裏面有一段很重要的信息 [可愛]
<< 要我自己發現嗎
<< 還是以後再告訴我
>> 自己發現咯
>> 不過晚上24:00之前會給你答案的
>> 在此之前,就看你咯 [可愛]
不過在這裏,千千再給大家透露一張圖,是public.png經過某種處理之後的圖片
>> 要我告訴你答案嘛
<< 這哪能看出來
<< [doge]
>> 我可沒讓你看
>> [白眼]
<< 看了都看不出來,不看更不知道了
>> [托腮]
<< so
So,揭曉答案的時候到了。
圖片的每個像素點一般是由三種顏色組成(紅綠藍三原色),而每種顏色儲存使用了8bit
,而我們修改這8bit
的最低位,最多隻會對原來的數值影響1,也就是影響最小的一位,畢竟我們要最大程度保留圖片的可視性對吧!
修改顏色的最低位,這樣微小的差距,在人眼看來是看不出來區別的,這樣我們就可以使用這最低的一位來儲存我們自己的信息啦!
我的做法
因爲我是把一張圖片隱藏到了另一張圖片裏面了,可是空出來的1位我們如何來存儲同樣大小的另一張圖片呢?
這裏前提是兩張圖片同樣大小,也就是同樣多的像素點,對於這種情況,圖像的點陣如果不是稀疏矩陣的話我們就只能捨棄精度啦!
首先求出整個圖片的所有像素點顏色值的平均值,然後對於每一個點的顏色,大於平均值的設爲1,其餘設爲0,這樣處理的話,原本八位的信息便壓縮成了1位,也就只有兩種信號咯,解碼的時候可以黑白顯示。
加密
#! /usr/bin/env python3
from PIL import Image
import numpy as np
# 處理原圖
def dealsrc(filename):
arr = np.array(Image.open(filename))
arr[arr[:, :, 0] == 255] -= 1
return arr
# 處理需要隱藏的圖片
def dealmsg(filename):
# 打開圖片並轉換成8位像素黑白圖的數組
arr = np.array(Image.open(filename).convert('L'))
# 計算均值
limit = arr.mean()
arr[arr[:] < limit] = 0
arr[arr[:] >= limit] = 1
return arr
# 生成隱寫圖片
def makeshdf(srcname, msgname):
key_array = dealsrc(srcname)
pass_array = dealmsg(msgname)
key_array[:, :, 0] += pass_array
img = Image.fromarray(key_array)
img.save('public.png')
if __name__ == '__main__':
makeshdf('../key.png', '../pass.png')
解密
#! /usr/bin/env python3
from PIL import Image
import numpy as np
# 處理原圖
def dealsrc(filename):
arr = np.array(Image.open(filename))
arr[arr[:, :, 0] == 255] -= 1
return arr
# 生成隱寫圖片
def makemsgf(srcname, shdname):
key_array = dealsrc(srcname)
public_array = np.array(Image.open(shdname))
ans_array = (public_array[:, :, 0] - key_array[:, :, 0]) * 255
img = Image.fromarray(ans_array)
img.save('solve.png')
if __name__ == '__main__':
makemsgf('../key.png', '../public.png')
怎麼說呢?
使用的信息載體最好是無損壓縮的圖片格式,png就是這樣的格式,而jpg格式屬於有損壓縮,用它儲存信息的話可能會在壓縮過程中破壞。
因爲之前說過這樣的隱藏會損失圖片精度,所以解密出來的圖片也就只能是黑白格式的咯!
原圖
解密之後的圖片
0x03 以後再寫吧……
哈哈,是不是又發現了一片新大陸!
未知的祕密,未知的人兒
我啊,只要有一個人便足夠了,能傳達得到嗎,如果能就好了……