平安夜的祝福

原文地址:平安夜的祝福

本來想等文章收錄之後再發表到這裏的,然而一直沒有等到,不知道爲什麼;寫於2016年12月25日。


昨天是平安夜,收到了好多祝福,還有班長大大Apple(!phone)

BUT,我能直接看懂祝福的內容,這樣好沒有挑戰性哦。


想把自己的祝福隱藏在什麼裏面,然後發給想要告訴的人,畢竟我是計算機系的學生啦!


可是放在哪裏好呢?

  1. 加密成字串

    • 可以直接被破譯的有base64,可是看起來好簡單

    • 自己寫的話在大一就已經做過了,不想重複

    • 其他的,或許很難破解咯

  2. 隱藏在圖片裏面
    • 以前沒有做過的事情,可以嘗試
    • 會讓對方想到文字就在圖片裏面的陷阱


接下來就給大家說兩種簡單的隱寫方法吧

0x00 圖種

因爲一張正常的jpg圖片是以FF D9作爲結束標誌的,而圖片查看器在打開圖片的時候會忽略結束符之後的內容,因此,我們可以在圖片的結束符之後追加我們自己想要隱藏的信息。

img


我們需要製作一個zip文件,放入想要隱藏的內容,再找一張jpg格式的圖片,以二進制方式把兩個文件首尾相接即可。

Windows :copy /b photo.jpg+file.zip output.jpg

Linux :cat file.zip >> photo.jpg

缺點是這樣的方式隱藏的信息很容易被發現,因爲只需要看看jpg圖片的FF D9之後有沒有內容便可知道真相。


0x01 平安夜的驚喜

public.png

public.png

key.png

key.png

key.png是原圖,我在它裏面添加了自己想要說的話,然後public.png是處理之後的圖片,你能在其中找到答案麼?


還有的就是,我把它發給了我最最最最最要好的朋友[害羞]:

>> 吶,這兩個 [可愛]
<< 這兩個有什麼區別 [小糾結]
>> 不告訴你
<< [doge]
>> 裏面有一段很重要的信息 [可愛]
<< 要我自己發現嗎
<< 還是以後再告訴我
>> 自己發現咯
>> 不過晚上24:00之前會給你答案的
>> 在此之前,就看你咯 [可愛]


不過在這裏,千千再給大家透露一張圖,是public.png經過某種處理之後的圖片

public2.png

>> 要我告訴你答案嘛
<< 這哪能看出來
<< [doge]
>> 我可沒讓你看
>> [白眼]
<< 看了都看不出來,不看更不知道了
>> [托腮]
<< so


So,揭曉答案的時候到了。

圖片的每個像素點一般是由三種顏色組成(紅綠藍三原色),而每種顏色儲存使用了8bit,而我們修改這8bit的最低位,最多隻會對原來的數值影響1,也就是影響最小的一位,畢竟我們要最大程度保留圖片的可視性對吧!

img

修改顏色的最低位,這樣微小的差距,在人眼看來是看不出來區別的,這樣我們就可以使用這最低的一位來儲存我們自己的信息啦!

img


我的做法

因爲我是把一張圖片隱藏到了另一張圖片裏面了,可是空出來的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格式屬於有損壓縮,用它儲存信息的話可能會在壓縮過程中破壞。

因爲之前說過這樣的隱藏會損失圖片精度,所以解密出來的圖片也就只能是黑白格式的咯!


原圖

img

解密之後的圖片

img


0x03 以後再寫吧……


哈哈,是不是又發現了一片新大陸!


未知的祕密,未知的人兒

我啊,只要有一個人便足夠了,能傳達得到嗎,如果能就好了……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章