天天看點

基于24位bmp圖檔資料區隐寫的實作

要在bmp圖像進行資料區隐寫,必須要知道它的資料結構。否則,可能會破壞圖像。 這是bmp的檔案結構。

    位圖檔案頭(bitmap-file header)包含了圖像類型、圖像大小、圖像資料存放位址和兩個保留未使用的字段。(14位元組)

    位圖資訊頭(bitmap-information header)(40位元組)

    彩色表/調色闆(color table)[24位bmp圖沒有調色闆]

    位圖資料(bitmap-data)

24位bmp圖像資料存儲的是實際的顔色資料,每個像素用3位元組表示,分别是紅綠藍。檔案頭和資訊頭共占了54個位元組。 

基于24位bmp圖檔資料區隐寫的實作

将bmp和txt讀入之後,其實就是兩個字元串。接下來要做的就是設計一個算法讓它們合并。 考慮到如果直接替換資料區字元。會使像素點有巨大改變。是以,每個字元我隻改末尾的一個bit,這樣一來,像素點的變化會非常小,幾乎沒有差別。而且,我盡可能讓更改的bit分散在資料區。為了友善提取,我在保留區記錄了兩個值,他們的異或值就是資料區隐藏資訊位元組的間隔值。

<code>01</code>

<code>//hid.cpp  by kryptosx</code>

<code>02</code>

<code>//隐藏程式代碼</code>

<code>03</code>

<code>#include &lt;iostream&gt;</code>

<code>04</code>

<code>#include &lt;fstream&gt;</code>

<code>05</code>

<code>#include &lt;bitset&gt;</code>

<code>06</code>

<code>#include&lt;cstdlib&gt;</code>

<code>07</code>

<code>#include "stdio.h"</code>

<code>08</code>

<code>using</code> <code>namespace</code> <code>std;</code>

<code>09</code>

<code>string pstr;</code>

<code>10</code>

<code>string tstr;</code>

<code>11</code>

<code>string stemp;</code>

<code>12</code>

<code>const</code> <code>int</code> <code>py=54;             </code><code>//資料區開始位置(因為從0算起)</code>

<code>13</code>

<code>int</code> <code>main(</code><code>int</code> <code>argc, </code><code>char</code><code>* argv[])</code>

<code>14</code>

<code>{</code>

<code>15</code>

<code>    </code><code>if</code><code>(argc!=3)</code>

<code>16</code>

<code>    </code><code>{</code>

<code>17</code>

<code>        </code><code>puts</code><code>(</code><code>"error:參數錯誤"</code><code>);</code>

<code>18</code>

<code>        </code><code>return</code> <code>0;</code>

<code>19</code>

<code>    </code><code>}</code>

<code>20</code>

<code>    </code><code>ifstream pic(argv[1]);</code>

<code>21</code>

<code>    </code><code>ifstream txt(argv[2]);</code>

<code>22</code>

<code>    </code><code>if</code><code>(!pic.is_open() || !txt.is_open())</code>

<code>23</code>

<code>24</code>

<code>        </code><code>perror</code><code>(</code><code>"檔案打開失敗"</code><code>);</code>

<code>25</code>

<code>26</code>

<code>27</code>

<code>    </code><code>while</code><code>(getline(pic,stemp))</code>

<code>28</code>

<code>29</code>

<code>        </code><code>pstr+=stemp;</code>

<code>30</code>

<code>        </code><code>stemp.clear();</code>

<code>31</code>

<code>32</code>

<code>    </code><code>while</code><code>(getline(txt,stemp))</code>

<code>33</code>

<code>34</code>

<code>        </code><code>tstr+=stemp;</code>

<code>35</code>

<code>36</code>

<code>37</code>

<code>    </code><code>int</code> <code>pl=pstr.size();</code>

<code>38</code>

<code>    </code><code>int</code> <code>tl=tstr.size();    </code>

<code>39</code>

<code>    </code> 

<code>40</code>

<code>    </code><code>if</code><code>(tl&gt;100)</code>

<code>41</code>

<code>42</code>

<code>        </code><code>puts</code><code>(</code><code>"字元過多"</code><code>);</code>

<code>43</code>

<code>        </code><code>printf</code><code>(</code><code>"%d"</code><code>,tl);</code>

<code>44</code>

<code>45</code>

<code>46</code>

<code>    </code><code>if</code><code>(tl==0)</code>

<code>47</code>

<code>48</code>

<code>        </code><code>puts</code><code>(</code><code>"沒有字元"</code><code>);</code>

<code>49</code>

<code>        </code><code>return</code> <code>0; </code>

<code>50</code>

<code>51</code>

<code>    </code><code>int</code> <code>ty=(pl-py)/(tl*8);        </code><code>//計算間隔</code>

<code>52</code>

<code>    </code><code>int</code> <code>tp=</code><code>rand</code><code>()%256;</code>

<code>53</code>

<code>    </code><code>pstr[6]=tl^tp;</code>

<code>54</code>

<code>    </code><code>pstr[7]=tp;            </code><code>//記錄隐藏資訊的長度到保留區中</code>

<code>55</code>

<code>    </code><code>for</code><code>(</code><code>int</code> <code>i=py,j=0;j!=tl;++j)          </code><code>//把隐藏的資訊轉化成bit,寫入到間隔的位元組的最後一位。</code>

<code>56</code>

<code>57</code>

<code>         </code><code>bitset&lt;8&gt; bt(tstr[j]);</code>

<code>58</code>

<code>         </code><code>for</code><code>(</code><code>int</code> <code>k=0;k!=8;k++)</code>

<code>59</code>

<code>         </code><code>{</code>

<code>60</code>

<code>             </code><code>if</code><code>(bt[8-k-1]==</code><code>true</code><code>) pstr[i]|=1;      </code>

<code>61</code>

<code>             </code><code>else</code> <code>pstr[i]&amp;=~1;           </code>

<code>62</code>

<code>             </code><code>i+=ty;</code>

<code>63</code>

<code>         </code><code>}</code>

<code>64</code>

<code>65</code>

<code>    </code><code>ofstream out(</code><code>"out.bmp"</code><code>);</code>

<code>66</code>

<code>    </code><code>out&lt;&lt;pstr&lt;&lt;endl;</code>

<code>67</code>

<code>    </code><code>pic.close();          </code><code>//關閉檔案流</code>

<code>68</code>

<code>    </code><code>txt.close();</code>

<code>69</code>

<code>    </code><code>out.close();</code>

<code>70</code>

<code>    </code><code>return</code> <code>0;</code>

<code>71</code>

<code>}</code>

<code>//creck.cpp by kryptosx</code>

<code>//資料提取代碼</code>

<code>const</code> <code>int</code> <code>py=54;</code>

<code>    </code><code>if</code><code>(argc!=2)</code>

<code>    </code><code>if</code><code>(!pic.is_open())</code>

<code>    </code><code>}   </code>

<code>    </code><code>int</code> <code>pl=pstr.size(); </code>

<code>    </code><code>int</code> <code>tl=pstr[6]^pstr[7];         </code><code>//從保留區提取出隐藏資訊的長度 </code>

<code>    </code><code>int</code> <code>ty=(pl-py)/(tl*8);       </code><code>//計算間隔 </code>

<code>    </code><code>char</code> <code>temp=0;</code>

<code>    </code><code>ofstream out(</code><code>"out.txt"</code><code>);</code>

<code>    </code><code>for</code><code>(</code><code>int</code> <code>i=py,j=0;j!=tl;++j)   </code><code>//提取每個隐寫位元組末尾的bit,然後重組成隐藏資訊。 </code>

<code>         </code><code>temp=0;</code>

<code>             </code><code>temp&lt;&lt;=1;</code>

<code>             </code><code>temp+=bitset&lt;8&gt;(pstr[i])[0];</code>

<code>         </code><code>out&lt;&lt;temp;</code>

<code>    </code><code>pic.close();</code>

這是一個很簡單的圖檔資料區隐寫程式,基于24位bmp圖像。基本實作了需要的功能,分散的寫入使得肉眼難以發現異常,其次,無需原圖也可以提取資訊。