So I'm doing one of the Princeton exercises here: http://www.cs.princeton.edu/courses/archive/fall10/cos126/assignments/lfsr.html and I've fully tested by LFSR class with the data that has been provided, so I'm sure I haven't gone wrong there. However, my PhotoMagic class yields an encrypted photo of 开发者_开发知识库the pipe as below:
This is not how it should appear. Any idea as to where my code has gone awry?
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);
}
}
You need to pad the result of Integer.toBinaryString() when calculating newRed, newGreen and newBlue. It may not have length 8.
The issue is likely in this block of code
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;
}
Note that your newPattern
starts off as the string of length zero, and then you add a text zero to it for each of the bits in bitPattern
. Then you add the bitPattern
back into the newPattern
and return the result. This leads to a 100% non-random result which is a zero padded version of the same bitPattern
you just submitted.
So if the input is
0010101101
the output will be
00000000000010101101
Which (when dropping the leading zeros) is exactly the input
0010101101
Since there is no added complexity, it doesn't mess up the mind's ability at edge detection: is quite easy to see the pattern.
I modified as follows. It worked.
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)));
精彩评论