<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何使用 Python 隱藏圖像中的數(shù)據(jù)

          共 6341字,需瀏覽 13分鐘

           ·

          2022-03-02 20:06

          隱寫術(shù)是在任何文件中隱藏秘密數(shù)據(jù)的藝術(shù)。


          秘密數(shù)據(jù)可以是任何格式的數(shù)據(jù),如文本甚至文件。簡(jiǎn)而言之,隱寫術(shù)的主要目的是隱藏任何文件(通常是圖像、音頻或視頻)中的預(yù)期信息,而不實(shí)際改變文件的外觀,即文件外觀看起來和以前一樣。


          在這篇文章中,我們將重點(diǎn)學(xué)習(xí)基于圖像的隱寫術(shù),即在圖像中隱藏秘密數(shù)據(jù)。


          但在深入研究之前,讓我們先看看圖像由什么組成:


          1. 像素是圖像的組成部分。

          2. 每個(gè)像素包含三個(gè)值:(紅色、綠色、藍(lán)色)也稱為 RGB 值。

          3. 每個(gè) RGB 值的范圍從 0 到 255。


          現(xiàn)在,讓我們看看如何將數(shù)據(jù)編碼和解碼到我們的圖像中。


          編碼

          有很多算法可以用來將數(shù)據(jù)編碼到圖像中,實(shí)際上我們也可以自己制作一個(gè)。在這篇文章中使用的一個(gè)很容易理解和實(shí)現(xiàn)的算法。


          算法如下:


          1. 對(duì)于數(shù)據(jù)中的每個(gè)字符,將其 ASCII 值轉(zhuǎn)換為 8 位二進(jìn)制 [1]。

          2. 一次讀取三個(gè)像素,其總 RGB 值為 3*3=9 個(gè)。前八個(gè) RGB 值用于存儲(chǔ)一個(gè)轉(zhuǎn)換為 8 位二進(jìn)制的字符。

          3. 比較相應(yīng)的RGB值和二進(jìn)制數(shù)據(jù)。如果二進(jìn)制數(shù)字為 1,則 RGB 值將轉(zhuǎn)換為奇數(shù),否則為偶數(shù)。

          4. 第 9 個(gè)值確定是否應(yīng)該讀取更多像素。如果有更多數(shù)據(jù)要讀取,即編碼或解碼,則第 9 個(gè)像素變?yōu)榕紨?shù);否則,如果我們想停止進(jìn)一步讀取像素,那就讓它變得奇數(shù)。


          重復(fù)這個(gè)過程,直到所有數(shù)據(jù)都被編碼到圖像中。


          例子

          假設(shè)要隱藏的消息是‘Hii’。

          消息是三個(gè)字節(jié),因此,對(duì)數(shù)據(jù)進(jìn)行編碼所需的像素為 3 x 3 = 9。考慮一個(gè) 4 x 3 的圖像,總共有 12 個(gè)像素,這足以對(duì)給定的數(shù)據(jù)進(jìn)行編碼。

          [(27, 64, 164), (248, 244, 194), (174, 246, 250), (149, 95, 232),(188, 156, 169), (71, 167, 127), (132, 173, 97), (113, 69, 206),(255, 29, 213), (53, 153, 220), (246, 225, 229), (142, 82, 175)]


          第 1 步

          H 的 ASCII 值為 72 ,其二進(jìn)制等效值為 01001000 。


          第 2 步

          讀取前三個(gè)像素。

          (27, 64, 164), (248, 244, 194), (174, 246, 250)


          第 3 步

          現(xiàn)在,將像素值更改為奇數(shù)為 1,偶數(shù)為 0,就像在二進(jìn)制等效數(shù)據(jù)中一樣。


          例如,第一個(gè)二進(jìn)制數(shù)字是0,第一個(gè) RGB 值是 27 ,它需要轉(zhuǎn)換為偶數(shù),這意味著 26 。類似地,64 被轉(zhuǎn)換為 63 因?yàn)橄乱粋€(gè)二進(jìn)制數(shù)字是1 所以 RGB 值應(yīng)該是奇數(shù)。


          因此,修改后的像素為:

          (26, 63, 164), (248, 243, 194), (174, 246, 250)


          第4步

          由于我們必須對(duì)更多數(shù)據(jù)進(jìn)行編碼,因此最后一個(gè)值應(yīng)該是偶數(shù)。同樣,i可以在這個(gè)圖像中進(jìn)行編碼。


          通過執(zhí)行 +1 或 -1 使像素值成為奇數(shù)/偶數(shù)時(shí),我們應(yīng)該注意二進(jìn)制條件。即像素值應(yīng)大于或等于 0 且小于或等于 255 。


          新圖像將如下所示:

          [(26, 63, 164), (248, 243, 194), (174, 246, 250), (148, 95, 231),(188, 155, 168), (70, 167, 126), (132, 173, 97), (112, 69, 206),(254, 29, 213), (53, 153, 220), (246, 225, 229), (142, 82, 175)]


          解碼

          對(duì)于解碼,我們將嘗試找到如何逆轉(zhuǎn)之前我們用于數(shù)據(jù)編碼的算法。


          1. 同樣,一次讀取三個(gè)像素。前 8 個(gè) RGB 值為我們提供了有關(guān)機(jī)密數(shù)據(jù)的信息,第 9 個(gè)值告訴我們是否繼續(xù)前進(jìn)。

          2. 對(duì)于前八個(gè)值,如果值為奇數(shù),則二進(jìn)制位為 1 ,否則為 0 。

          3. 這些位連接成一個(gè)字符串,每三個(gè)像素,我們得到一個(gè)字節(jié)的秘密數(shù)據(jù),這意味著一個(gè)字符。

          4. 現(xiàn)在,如果第 9 個(gè)值是偶數(shù),那么我們繼續(xù)一次讀取三個(gè)像素,否則,我們停止。


          例如

          讓我們開始一次讀取三個(gè)像素。

          考慮我們之前編碼的圖像。

          [(26, 63, 164), (248, 243, 194), (174, 246, 250), (148, 95, 231),(188, 155, 168), (70, 167, 126), (132, 173, 97), (112, 69, 206),(254, 29, 213), (53, 153, 220), (246, 225, 229), (142, 82, 175)]


          第1步

          我們首先讀取三個(gè)像素:


          [(26, 63, 164), (248, 243, 194), (174, 246, 250)


          第2步

          讀取第一個(gè)值:26,它是偶數(shù),因此二進(jìn)制位是 0 。類似地,對(duì)于 63 ,二進(jìn)制位是 1 ,對(duì)于 164 它是 0 。這個(gè)過程一直持續(xù)到 8 個(gè) RGB 值。


          第 3 步

          將所有二進(jìn)制值連接后,我們最終得到二進(jìn)制值:01001000。最終的二進(jìn)制數(shù)據(jù)對(duì)應(yīng)于十進(jìn)制值 72,在 ASCII 中,它代表字符 H 。


          第 4 步

          由于第 9 個(gè)值是偶數(shù),我們重復(fù)上述步驟。當(dāng)遇到的第 9 個(gè)值是奇數(shù)時(shí),我們停止。


          結(jié)果,我們得到了原始信息,即 Hii 。


          上述算法的 Python 程序如下:

          # Python program implementing Image Steganography
          # PIL module is used to extract# pixels of image and modify itfrom PIL import Image
          # Convert encoding data into 8-bit binary# form using ASCII value of charactersdef genData(data):
          # list of binary codes # of given data newd = []
          for i in data: newd.append(format(ord(i), '08b')) return newd
          # Pixels are modified according to the# 8-bit binary data and finally returneddef modPix(pix, data):
          datalist = genData(data) lendata = len(datalist) imdata = iter(pix)
          for i in range(lendata):
          # Extracting 3 pixels at a time pix = [value for value in imdata.__next__()[:3] + imdata.__next__()[:3] + imdata.__next__()[:3]]
          # Pixel value should be made # odd for 1 and even for 0 for j in range(0, 8): if (datalist[i][j] == '0' and pix[j]% 2 != 0): pix[j] -= 1
          elif (datalist[i][j] == '1' and pix[j] % 2 == 0): if(pix[j] != 0): pix[j] -= 1 else: pix[j] += 1 # pix[j] -= 1
          # Eighth pixel of every set tells # whether to stop ot read further. # 0 means keep reading; 1 means thec # message is over. if (i == lendata - 1): if (pix[-1] % 2 == 0): if(pix[-1] != 0): pix[-1] -= 1 else: pix[-1] += 1
          else: if (pix[-1] % 2 != 0): pix[-1] -= 1
          pix = tuple(pix) yield pix[0:3] yield pix[3:6] yield pix[6:9]
          def encode_enc(newimg, data): w = newimg.size[0] (x, y) = (0, 0)
          for pixel in modPix(newimg.getdata(), data):
          # Putting modified pixels in the new image newimg.putpixel((x, y), pixel) if (x == w - 1): x = 0 y += 1 else: x += 1
          # Encode data into imagedef encode(): img = input("Enter image name(with extension) : ") image = Image.open(img, 'r')
          data = input("Enter data to be encoded : ") if (len(data) == 0): raise ValueError('Data is empty')
          newimg = image.copy() encode_enc(newimg, data)
          new_img_name = input("Enter the name of new image(with extension) : ") newimg.save(new_img_name, str(new_img_name.split(".")[1].upper()))
          # Decode the data in the imagedef decode(): img = input("Enter image name(with extension) : ") image = Image.open(img, 'r')
          data = '' imgdata = iter(image.getdata())
          while (True): pixels = [value for value in imgdata.__next__()[:3] + imgdata.__next__()[:3] + imgdata.__next__()[:3]]
          # string of binary data binstr = ''
          for i in pixels[:8]: if (i % 2 == 0): binstr += '0' else: binstr += '1'
          data += chr(int(binstr, 2)) if (pixels[-1] % 2 != 0): return data
          # Main Functiondef main(): a = int(input(":: Welcome to Steganography ::\n" "1. Encode\n2. Decode\n")) if (a == 1): encode()
          elif (a == 2): print("Decoded Word : " + decode()) else: raise Exception("Enter correct input")
          # Driver Codeif __name__ == '__main__' :
          # Calling main function main()

          程序中使用的模塊是 PIL ,它代表Python 圖像庫(kù),它使我們能夠在 Python 中對(duì)圖像執(zhí)行操作。


          程序執(zhí)行


          數(shù)據(jù)編碼


          數(shù)據(jù)解碼


          輸入圖像


          輸出圖像


          局限性

          該程序可能無法對(duì) JPEG 圖像按預(yù)期處理,因?yàn)?JPEG 使用有損壓縮,這意味著修改像素以壓縮圖像并降低質(zhì)量,因此會(huì)發(fā)生數(shù)據(jù)丟失。


          參考

          1. https://www.geeksforgeeks.org/program-decimal-binary-conversion/

          2. https://www.geeksforgeeks.org/working-images-python/

          3. https://dev.to/erikwhiting88/let-s-hide-a-secret-message-in-an-image-with-python-and-opencv-1jf5

          4. A code along with the dependencies can be found here:?https://github.com/goelashwin36/image-steganography

          END


          各位伙伴們好,詹帥本帥搭建了一個(gè)個(gè)人博客和小程序,匯集各種干貨和資源,也方便大家閱讀,感興趣的小伙伴請(qǐng)移步小程序體驗(yàn)一下哦!(歡迎提建議)

          推薦閱讀


          牛逼!Python常用數(shù)據(jù)類型的基本操作(長(zhǎng)文系列第①篇)

          牛逼!Python的判斷、循環(huán)和各種表達(dá)式(長(zhǎng)文系列第②篇)

          牛逼!Python函數(shù)和文件操作(長(zhǎng)文系列第③篇)

          牛逼!Python錯(cuò)誤、異常和模塊(長(zhǎng)文系列第④篇)


          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产麻豆成人免费视频 | 亚洲人天堂 | 九一国产视频 | 免费欧美黄色 | 青青草在线观看免费视频 |