2011-05-31 49 views
1

所以我在這裏做普林斯頓的一個練習:http://www.cs.princeton.edu/courses/archive/fall10/cos126/assignments/lfsr.html 我已經完全通過LFSR類測試了所提供的數據,所以我確信我在那裏沒有出錯。但是,我的PhotoMagic類生成管道的加密照片,如下所示:Encrypted photo of the Pipe image無法找出此代碼中的錯誤

這不是它應該如何顯示。任何關於我的代碼出錯的想法?

import java.awt.Color; 

public class PhotoMagic 
{ 
    private LFSR lfsr; 

public static void main(String args[]) 
{ 
    new PhotoMagic("src/pictures/shield.png","01101000010100010000",16); 

} 

public PhotoMagic(String imageName,String binaryPassword,int tap) 
{ 
    Picture pic = new Picture(imageName); 
    lfsr = new LFSR(binaryPassword,tap); 


    for (int x = 0; x < pic.width(); x++) 
    { 
     for (int y = 0; y < pic.height(); y++) 
     { 
      Color color = pic.get(x, y); 
      int red = color.getRed(); 
      int blue = color.getBlue(); 
      int green = color.getGreen(); 
      int transparency = color.getTransparency(); 
      int alpha = color.getAlpha(); 

      int newRed = xor(Integer.toBinaryString(red),paddedBitPattern(lfsr.generate(8))); 

      int newGreen = xor(Integer.toBinaryString(green),paddedBitPattern(lfsr.generate(8))); 

      int newBlue = xor(Integer.toBinaryString(blue),paddedBitPattern(lfsr.generate(8))); 

      Color newColor = new Color(newRed, newGreen, newBlue); 
      pic.set(x, y, newColor); 
     } 
    } 
    pic.show(); 
} 

/** 
* Pads bit pattern to the left with 0s if it is not 8 bits long 
* @param bitPattern 
* @return 
*/ 
public String paddedBitPattern(int bitPattern) 
{ 
    String tempBit = Integer.toBinaryString(bitPattern); 
    String newPattern = ""; 
    for(int i = 1; i < 9-tempBit.length(); i++) 
    { 
     newPattern += "0"; 
    } 
    newPattern += tempBit; 
    return newPattern; 
} 

/** 
* Performs the bitwise XOR 
* @param colorComponent 
* @param generatedBit 
* @return 
*/ 
public int xor(String colorComponent, String generatedBit) 
{ 
    String newColor = ""; 

    for(int i = 0; i < colorComponent.length(); i++) 
    { 
     if(colorComponent.charAt(i) != generatedBit.charAt(i)) 
     { 
      newColor += 1; 
     } 
     else 
     { 
      newColor += 0; 
     } 
    } 
    return Integer.valueOf(newColor,2); 
} 

}

+0

你爲什麼要把所有東西都轉換成字符串呢?您可以直接在int上使用java xor運算符,並將代碼大小縮小一半。 – toto2 2011-05-31 15:08:52

回答

2

您需要在計算newRed,newGreen和newBlue時填充Integer.toBinaryString()的結果。它可能沒有長度8.

+0

+1好點。如果你正在處理16位RGBA值,那麼整個高位字節將完全不受影響。 – 2011-05-31 14:47:14

+0

謝謝!這確實是錯誤!該程序現在可以工作,圖像可以按照現在的分配進行加密和解密。 – nope 2011-05-31 15:00:17

2

的問題很可能在代碼

public String paddedBitPattern(int bitPattern) 
{ 
    String tempBit = Integer.toBinaryString(bitPattern); 
    String newPattern = ""; 
    for(int i = 1; i < 9-tempBit.length(); i++) 
    { 
     newPattern += "0"; 
    } 
    newPattern += tempBit; 
    return newPattern; 
} 

注意此塊你newPattern開始了作爲零長度的字符串,然後將文本零添加到它對於bitPattern中的每個位。然後,將bitPattern添加回newPattern並返回結果。這會導致100%的非隨機結果,這是您剛剛提交的相同bitPattern的零填充版本。

所以,如果輸入的是

0010101101 

輸出將是

00000000000010101101 

哪個(丟棄前導零的時候)是完全輸入

0010101101 

由於沒有增加了複雜性,但它並沒有擾亂人們在邊緣檢測方面的能力:很容易看到這種模式。

+0

抱歉,如果它不清楚,但傳入方法的唯一參數是介於0-255和0-255之間的十進制數,如果小於8位長,則它只是二進制等效值。所以42中的二進制是101010,但該方法將填充它,因此它看起來像00101010,它允許xor方法操縱它。所以這個bug是別的。 – nope 2011-05-31 14:31:54

+0

@tomejuan,好的,所以它的'應該是一個字符串轉換器只。但是,異或實現不能混合它所包含的單個位。這意味着如果你不轉移你的位(通過旋轉或其他方式),你可以找回數據,保留超出密鑰長度邊界的數值趨勢。圖片在這裏和那裏只需要幾個邊界就可以識別,所以你會找回看起來像一個標有「這不是管道」的管道。如果要將密鑰擴展爲8x8位,請在每次傳遞paddedBitPattern後將其旋轉一位。 – 2011-05-31 14:36:08

+0

@tomejuan,另外8位對於圖像上的異或加密是一個非常糟糕的邊界。它的使用是因爲它的計算效率高且易於編程;但是,RGBA的邊界對於紅色,綠色,藍色和Alpha有8位。所以,每一位只是在顏色上改變,而與位於其旁邊的像素無關。人類可以很容易識別一棵樹,即使它是藍色的。色彩轉移不會讓您的照片更難辨認。 – 2011-05-31 14:41:27

0

我修改如下。有效。

int newRed = xor(paddedBitPattern(red),paddedBitPattern(lfsr.generate(8)));  
int newGreen = xor(paddedBitPattern(green),paddedBitPattern(lfsr.generate(8))); 
int newBlue = xor(paddedBitPattern(blue),paddedBitPattern(lfsr.generate(8)));