<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>

          基于matlab和python的LSB隱寫實現(xiàn)

          共 8365字,需瀏覽 17分鐘

           ·

          2021-04-10 10:16

          LSB隱寫技術(shù)

          LSB全稱為 least significant bit,是最低有效位的意思。Lsb圖片隱寫是基于lsb算法的一種圖片隱寫術(shù)。


          在二進制數(shù)中意為最低有效位,一般來說,MSB(最高有效位)位于二進制數(shù)的最左側(cè),LSB位于二進制數(shù)的最右側(cè)。


          由于圖像的每一個像素點都是由RGB(紅、綠、藍)三原色組成,而這三種顏色又可以組合成各種其它顏色,每個顏色占8位(如#FFFFFF),LSB隱寫即是修改每個顏色值的最低一位,將其替換為我們想要嵌入的信息中的內(nèi)容,以此來實現(xiàn)數(shù)據(jù)隱藏。


          一個像素點包含三種顏色,每個顏色修改最后1位,這樣一個像素點就可以攜帶3位信息。


          應(yīng)用LSB算法的圖像格式需為位圖形式,即圖像不能經(jīng)過壓縮,如LSB算法多應(yīng)用于png、bmp等格式,而jpg格式較少。


          首先來講png圖片,png圖片是一種無損壓縮的位圖片形格式,也只有在無損壓縮或者無壓縮的圖片(BMP)上實現(xiàn)lsb隱寫。如果圖像是jpg圖片的話,就沒法使用lsb隱寫了,原因是jpg圖片對像數(shù)進行了有損壓縮,我們修改的信息就可能會在壓縮的過程中被破壞。而png圖片雖然也有壓縮,但卻是無損壓縮,這樣我們修改的信息也就能得到正確的表達,不至于丟失。BMP的圖片也是一樣的,是沒有經(jīng)過壓縮的。BMP圖片一般是特別的大的,因為BMP把所有的像數(shù)都按原樣儲存,沒有進行壓縮。


          png圖片中的圖像像數(shù)一般是由RGB三原色(紅綠藍)組成,每一種顏色占用8位,取值范圍為0x00~0xFF,即有256種顏色,一共包含了256的3次方的顏色,即16777216種顏色。而人類的眼睛可以區(qū)分約1000萬種不同的顏色,這就意味著人類的眼睛無法區(qū)分余下的顏色大約有6777216種。


          LSB隱寫就是修改RGB顏色分量的最低二進制位也就是最低有效位(LSB),而人類的眼睛不會注意到這前后的變化,每個像數(shù)可以攜帶3比特的信息。



          上圖我們可以看到,十進制的235表示的是綠色,我們修改了在二進制中的最低位,但是顏色看起來依舊沒有變化。我們就可以修改最低位中的信息,實現(xiàn)信息的隱寫。我修改最低有效位的信息的算法就叫做lsb加密算法,提取最低有效位信息的算法叫做lsb解密算法。


          再放兩張圖加深下理解:


          順序嵌入


          順序嵌入很簡單,遍歷每個像素點,然后將二進制嵌入最后一位即第八位即可。


          畫了一個流程圖,這里貼上來方便理解:

          python版本


          首先我用python實現(xiàn)了一個,利用python3的PIL庫寫起來還是很簡單的。直接看代碼吧

          # coding:utf-8# python 3.6.6
          from PIL import Imageimport time
          # 將字符串轉(zhuǎn)為二進制def str_convert_bin(s): result = '' for c in s: b = bin(ord(c)).replace('0b', '') b = '0'*(7-len(b))+b result = result+b return result
          # 將二進制轉(zhuǎn)化為字符串def bin_convert_str(b): str='' # 將二進制字符串每7位分割,成列表 b1 = [b[i:i+7] for i in range(0, len(b), 7)] for i in range(len(b1)): b2 = chr(int(b1[i],2)) str = str+b2 return str
          # 將二進制字符串嵌入圖片像素B通道 im:Image()、bin1:要嵌入的二進制串def insert(im,bin1): size = im.size length = len(bin1) k=0 flag=0 for i in range(size[0]): for j in range(size[1]): # im.getpixel((i,j))讀取像素點(i,j)的像素值 pixel_b=bin(im.getpixel((i,j))[2]).replace('0b', '') if pixel_b[-1:]<bin1[k]: # im.putpixel((i,j),(x,y,z))設(shè)置像素點(i,j)的RGB值為(x,y,z) im.putpixel((i,j),(im.getpixel((i,j))[0],im.getpixel((i,j))[1],im.getpixel((i,j))[2]+1)) if pixel_b[-1:]>bin1[k]: im.putpixel((i,j),(im.getpixel((i,j))[0],im.getpixel((i,j))[1],im.getpixel((i,j))[2]-1)) k=k+1 if k==length: flag=1 break if flag==1: break print("字符串嵌入完成\n\n")
          # 提取字符串 im:Image()、length:二進制字符串長度def extract(im,length): size = im.size k=0 result='' flag=0 for i in range(size[0]): for j in range(size[1]): pixel_b=bin(im.getpixel((i,j))[2]).replace('0b', '') result=result+pixel_b[-1:] k=k+1 if k==length: flag=1 break if flag==1: break print("提取完成,二進制字符串為:\n%s"%result) str = bin_convert_str(result) print("轉(zhuǎn)換完成,結(jié)果為:\n%s"%str)
          def main(): test_str=input("請輸入字符串:\n") result = str_convert_bin(test_str) print("待嵌入字符串轉(zhuǎn)化為二進制為:\n%s"%result) print("開始嵌入....") im = Image.open("2.bmp") insert(im, result)
          time.sleep(5) print("開始提取字符串:") extract(im, len(result))
          if __name__=='__main__': main()

          結(jié)果:


          matlab版本


          后續(xù)更復(fù)雜的隱寫還是需要用到matlab,于是乎還是轉(zhuǎn)matlab吧。


          matlab就不介紹了,代碼寫得粗糙,勉強貼上代碼:

          % LSB隱藏(順序隱藏)% 可以隱藏數(shù)字、字母、英文字符 ex: hello,world.111% jpg失真!用png/bmp
          clear all;clc;data=imread('1.png'); % 讀入圖片str=input('請輸入要潛入的字符串:','s'); % 接收字符串str_bin_mat=dec2bin(str); % 字符串轉(zhuǎn)二進制矩陣
          % 二進制矩陣轉(zhuǎn)字符串l_str_bin_mat=size(str_bin_mat); %二進制矩陣str_bin='';for i=1:l_str_bin_mat(1) for j=1:l_str_bin_mat(2) str_bin=[str_bin,str_bin_mat(i,j)]; endenddisp('待嵌入的字符串二進制形式為');disp(str_bin);
          % 檢測是否能夠完全嵌入[l,w,h]=size(data);if length(str_bin)>=l*w*h error('字符長度超出!!!');end
          %嵌入程序data1=data;disp('開始嵌入');flag1=1; %輸入字符二進制長度,判斷嵌入是否結(jié)束flag2=1;flag3=1;for i=1:l if flag3==0 break end for j=1:w if flag2==0 flag3=0; break end for k=1:h if flag1>length(str_bin) disp('over'); flag2=0; break end a=dec2bin(data1(i,j,k),8);%數(shù)字取二進制 data1(i,j,k)=bin2dec([a(1:7),str_bin(flag1)]);%二進制相加,再取十進制 flag1=flag1+1; end endend%保存圖片imwrite(data1,'1-2.png')disp('嵌入完成,保存為1-2.png');
          %以下為提取程序disp('開始提取...')data2 = imread('1-2.png');[l,w,h]=size(data2);str_bin1='';%提取到的二進制字符串locationx=[];locationy=[];locationxy=[];m=length(str_bin);flag1=1;flag2=1;flag3=1;for i=1:l if flag3==0 break end for j=1:w if flag2==0 flag3=0; break end for k=1:h if flag1>length(str_bin) flag2=0; break end a=dec2bin(data2(i,j,k),8);%十進制轉(zhuǎn)二進制 str_bin1=[str_bin1,a(8)];% 取最后一個數(shù) flag1=flag1+1; end endenddisp('提取完成!');disp('提取到的二進制字符串為:');disp(str_bin1);disp('開始轉(zhuǎn)換...')
          % 二進制轉(zhuǎn)字符串str2='';for q=1:length(str_bin1)/l_str_bin_mat(2) w=str_bin1((q-1)*l_str_bin_mat(2)+1:q*l_str_bin_mat(2));%w為每七位 a=bin2dec(w); % 轉(zhuǎn)換為十進制 if a>9 str2=[str2,char(a)]; end if a<9 str2=[str2,a]; endenddisp('轉(zhuǎn)換完成');disp('最終結(jié)果為:');disp(str2);

          可以嵌字符,數(shù)字,字母,結(jié)果如下:


          隨機LSB隱寫


          其實這個和順序差不多,無非就是在遍歷像素點的時候,將(i,j)改為隨機的點,我們可以寫個隨機函數(shù)隨機生成列表X和Y,當要嵌入(i,j)時我們就將其變?yōu)?X(i+j), Y(i+j)),為什么不是(X(i), Y(j))讀者可以想想(這樣不隨機)。



          接下來看生成隨機列表的函數(shù) randomxy.m:


          % 隨機生成兩個列表% l為長,w為寬,len_str_bin為嵌入二進制長度,key為隨機種子function [x,y]=randxy(l,w,len_str_bin,key)    %設(shè)置隨機種子,生成一串隨機數(shù)    rand('seed',key);    disp('hhhhhhhhh');    x=randperm(l,len_str_bin);    y=randperm(w,len_str_bin);    %x = unique(x); %去重處理    %y = unique(y) ;%去重處理end

          然后看主要代碼:

          % By gengyanqing% LSB隱藏(隨機隱藏)% 可以隱藏數(shù)字、字母、英文字符 ex: hello,world.111% jpg失真!用png/bmp
          clear all;clc;data=imread('1.png'); % 讀入圖片str=input('請輸入要潛入的字符串:','s'); % 接收字符串str_bin_mat=dec2bin(str); % 字符串轉(zhuǎn)二進制矩陣
          % 二進制矩陣轉(zhuǎn)字符串l_str_bin_mat=size(str_bin_mat); %二進制矩陣str_bin='';for i=1:l_str_bin_mat(1) for j=1:l_str_bin_mat(2) str_bin=[str_bin,str_bin_mat(i,j)]; endenddisp('待嵌入的字符串二進制形式為');disp(str_bin);
          % 檢測是否能夠完全嵌入[l,w,h]=size(data);if length(str_bin)>=l*w*h error('字符長度超出!!!');end
          %嵌入程序data1=data;disp('開始嵌入');flag1=1; %輸入字符二進制長度,判斷嵌入是否結(jié)束flag2=1;flag3=1;% 調(diào)用randxy函數(shù)[x,y]=randxy(l,w,length(str_bin),88);for i=1:l if flag3==0 break end for j=1:w if flag2==0 flag3=0; break end for k=1:h if flag1>length(str_bin) disp('over'); flag2=0; break end a=dec2bin(data1(x(i+j),y(i+j),k),8);%數(shù)字取二進制 data1(x(i+j),y(i+j),k)=bin2dec([a(1:7),str_bin(flag1)]);%二進制相加,再取十進制 flag1=flag1+1; end endend%保存圖片imwrite(data1,'1-2.png')disp('嵌入完成,保存為1-2.png');
          %以下為提取程序%這里提供了x和y,提取二進制字符串位數(shù)的信息disp('開始提取...')data2 = imread('1-2.png');[l,w,h]=size(data2);str_bin1='';%提取到的二進制字符串locationx=[];locationy=[];locationxy=[];m=length(str_bin);flag1=1;flag2=1;flag3=1;for i=1:l if flag3==0 break end for j=1:w if flag2==0 flag3=0; break end for k=1:h if flag1>length(str_bin) flag2=0; break end a=dec2bin(data2(x(i+j),y(i+j),k),8);%十進制轉(zhuǎn)二進制 locationx=[locationx,x(i+j)];%隨機點x坐標 locationy=[locationy,y(i+j)];%隨機點y坐標 locationxy=[locationxy;x(i+j),y(i+j),k]; str_bin1=[str_bin1,a(8)];% 取最后一個數(shù) flag1=flag1+1; end endenddisp('提取完成!');disp('提取到的二進制字符串為:');disp(str_bin1);disp('開始轉(zhuǎn)換...')
          % 二進制轉(zhuǎn)字符串str2='';for q=1:length(str_bin1)/l_str_bin_mat(2) w=str_bin1((q-1)*l_str_bin_mat(2)+1:q*l_str_bin_mat(2));%w為每七位 a=bin2dec(w); % 轉(zhuǎn)換為十進制 if a>9 str2=[str2,char(a)]; end if a<9 str2=[str2,a]; endenddisp('轉(zhuǎn)換完成');disp('最終結(jié)果為:');disp(str2);
          disp('隨機位置分別為');disp(locationxy);plot(locationx,locationy);


          結(jié)果:


          下圖為隱藏點的圖(可以看出來確實是隨機的)


          「?? 感謝大家」

          如果你覺得這篇內(nèi)容對你挺有有幫助的話:

          1. 點贊支持下吧,讓更多的人也能看到這篇內(nèi)容(收藏不點贊,都是耍流氓 -_-)
          2. 歡迎在留言區(qū)與我分享你的想法,也歡迎你在留言區(qū)記錄你的思考過程。
          3. 覺得不錯的話,也可以閱讀近期梳理的文章(感謝鼓勵與支持??????):

          老鐵,三連支持一下,好嗎?↓↓↓


          歡迎大家加入到知識星球這個大家庭,這里一定有與你志同道合的小伙伴,在這里大家可以一起交流,一起學(xué)習,一同吹逼,一同玩耍。。。


          長按按鈕  “識別二維碼” 關(guān)注我
          更多精彩內(nèi)容等著你哦

          點分享

          點點贊

          點在

          瀏覽 114
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  无码欧美XXXXX | 久久久aV片 | 日本人妻精品 | 蒙古一级黄片 | 丰满老熟女 |