2014-10-28 138 views
0

我試圖改變圖像像素的LSB值,使得它與字符串「abc」匹配但添加1或0與奇值的像素被返回0 不一致值值這裏是代碼:改變LSB的圖像RGB值給予

public static void main(String[] args) { 
    BufferedImage img = null; 

    try { 
     img = ImageIO.read(new File("a.jpg")); 
    } catch (IOException ex) { 

    } 

    int pixel[] = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); 
    String s = "abc"; 
    byte[] b = s.getBytes(); 

    String f = ""; 
    for (int i = 0; i < b.length; i++) { 
     f += Integer.toBinaryString(b[i]); 
    } 

    f.trim(); 

    int[] newpixel = new int[pixel.length]; 
    for (int i = 0; i < pixel.length; i++) { 
     if (i < f.length()) { 
      if (pixel[i] % 2 == 0) { 
       if (f.charAt(i) == '0') { 
        newpixel[i] = pixel[i]; 
       } 
       if (f.charAt(i) == '1') { 
        newpixel[i] = pixel[i] + 1; 
       } 
      } 
      if (pixel[i] % 2 == 1) { 
       if (f.charAt(i) == '0') { 
        newpixel[i] = pixel[i] - 1; 
       } 
       if (f.charAt(i) == '1') { 
        newpixel[i] = pixel[i]; 
       } 
      } 
     } else { 
      newpixel[i] = pixel[i]; 
     } 
    } 

    o: 
    for (int i = 0; i < img.getWidth() * img.getHeight(); i++) { 

     if (i < f.length()) { 
      System.out.print(" " + f.charAt(i) + ":(" + pixel[i] + "," + newpixel[i] + ")"); 
     } else { 
      break o; 
     } 

    } 

} 

並且輸出是:

1:( - 11235948,-11235947)1:( - 11893363,0)0:( - 11893617,0) 0:( - 10577497,0)0:( - 11695976,-11695976)0:( - 12090996,-12090996)1:( - 11170168,-11170167)1:( - 10775924,-10775923)1:( - 972 0:( - 9658965,0)0:( - 9856341,0)0:( - 11236466,-11236466)1:( - 11564174,-11564173)0:( - 11431819,0)1: 10380136,-10380135)1:( - 10973290,-10973289)0:( - 12093056,-12093056)0:( - 10842985,0)0:( - 10118999,0)1:( - 11368034,-11368033)1: (-11630686,-11630685)

回答

1

The modulo of a negative odd number does not return 1 in java,所以你的if (pixel[i] % 2 == 1)塊沒有執行。從上面的鏈接中,您可以通過編寫if ((((pixel[i] % 2) + 2) % 2) == 1)來獲得正數。然而,一個數字的奇偶性是排他性的,所以它不是偶數就是奇數。建議將代碼更改爲此代碼

if (pixel[i] % 2 == 0) { 
    ... 
} 
else { 
    ... 
} 

雖然您的代碼有另一個錯誤。行f += Integer.toBinaryString(b[i]);將字符轉換爲二進制字符串,但如果ascii字符的值小於128,則轉換將使用最小位數。例如,a = '1100001',它只有7位。你想填充0到左邊來獲得8位。快速搜索產生this和上面的行應更改爲

f += String.format("%8s", Integer.toBinaryString(b[i])).replace(' ', '0'); 

如果我可以推薦給你的代碼的一些可選的改進,如下

import java.util.Arrays; 

public static void main(String[] args) { 
    BufferedImage img = null; 

    try { 
     img = ImageIO.read(new File("a.jpg")); 
    } catch (IOException ex) { 

    } 

    int pixel[] = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); 
    int[] newpixel = Arrays.copyOf(pixel, pixel.length); 

    String s = "abc"; 
    byte[] b = s.getBytes(); 

    int count = 0; 
    for (int i = 0; i < b.length; i++) { 
     byte current_byte = b[i]; 
     for (int j = 7; j >= 0; j--) { 
      int lsb = (current_byte >> j) & 1; 
      newpixel[count] = (pixel[count] & 0xfffffffe) + lsb; 
      System.out.println(lsb + ":(" + pixel[count] + "," + newpixel[count] + ")"); 
      count++; 
     } 
    } 

    // Extraction sequence 
    String secret = ""; 
    int bit = 0; 
    for (int i = 0; i < b.length; i++) { 
     int ascii = 0; 
     for (int j = 7; j >=0; j--) { 
      ascii += (newpixel[bit] & 1) << j; 
      bit++; 
     } 
     secret += (char)ascii; 
    } 
    System.out.print(secret); 

} 

注意我會做到這一點:

Arrays.copyOf()是保持原始圖像的副本比較差異的緣故。通常,我只是直接編輯0​​。

你不需要字節轉換爲1和0的字符串,因爲你需要這些數字爲整數以後。以下循環使用right bitshiftbitwise and操作將比特從最高有效位(最左邊)逐個提取到最低位。

for (int j = 7; j >=0; j--) { 
    int lsb = (b[i] >> j) & 1; 
} 

而不是檢查一個像素的LSB的值,你可以將它清零,然後從上面的循環添加LSB。您可以使用按位和操作來實現此目的。一個像素由四個字節組成,每個像素的最大值爲255(0xff)。這些字節對應於alpha透明度,紅色,綠色和藍色通道(稱爲ARGB)。你可以閱讀關於它here

newpixel[count] = (pixel[count] & 0xfffffffe) + lsb; 

提取過程與嵌入相反。但這裏有一個竅門。該程序在提取整個消息之前不知道要讀取多少個像素。你想要做的是引入一個長度變量,它等於8 * b.length。您可以分配前16個像素,以像您的角色一樣在1秒和0秒內隱藏此數字。提取然後讀取這第一個16像素,計算有多少像素要讀取,並從第17個像素開始。

+0

:但我認爲你的代碼會使代碼的提取有點困難。你可以建議我如何提取字符串。 – 2014-10-29 16:20:11

+0

我已經用提取snipet更新了答案。 – Reti43 2014-10-29 17:37:49

+0

:在將newpixel寫入jpg文件時,應該是什麼顏色模型?我嘗試了幾乎所有類型的顏色模型,但提取並不成功,雖然我的代碼在使用像素數組時工作正常。 – 2014-11-06 15:32:12