【问题标题】:Can't figure out the bug in this code无法找出此代码中的错误
【发布时间】:2011-05-31 14:18:18
【问题描述】:

所以我在这里做一项普林斯顿练习:http://www.cs.princeton.edu/courses/archive/fall10/cos126/assignments/lfsr.html 并且我已经使用提供的数据通过 LFSR 类进行了全面测试,所以我确信我没有出错。但是,我的 PhotoMagic 类会生成管道的加密照片,如下所示:

这不是它应该出现的样子。知道我的代码哪里出错了吗?

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);
}

}

【问题讨论】:

  • 为什么要将所有内容都转换为Strings?您可以直接在 int 上使用 java xor 运算符并将代码大小缩小一半。

标签: java image encryption feedback


【解决方案1】:

在计算 newRed、newGreen 和 newBlue 时,需要填充 Integer.toBinaryString() 的结果。它可能没有长度 8。

【讨论】:

  • +1 好点。如果您处理的是 16 位 RGBA 值,那么整个高字节将完全不受影响。
  • 谢谢!这确实是错误!该程序现在可以运行,并且可以按照现在的分配对图像进行加密和解密。
【解决方案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-255 之间的十进制数,如果它的长度小于 8 位,它只是二进制等效值。所以二进制中的 42 是 101010,但是该方法将填充它,因此它看起来像 00101010,这允许 xor 方法对其进行操作。所以这个错误是别的东西。
  • @tomejuan,好的,所以它应该只是字符串转换器。但是,XOR 实现不能混合超出它包含的单个位。这意味着,如果您不移动位(通过旋转或其他方式),您将获得保留超出密钥长度边界的值趋势的数据。图片只需要在这里和那里有几个边界即可识别,所以你会得到一个看起来像管子的东西,标有“这不是管子”。如果要将密钥扩展到 8x8 位,请在每次传递到 paddedBitPattern 后将密钥旋转一位。
  • @tomejuan,此外 8 位对于图像上的 XOR 加密来说是一个非常糟糕的边界。使用它是因为它计算效率高且易于编程;但是,RGBA 的边界有 8 位,分别代表 Red、Green、Blue 和 Alpha。因此,每一位都只改变颜色,与旁边的像素无关。人类可以很容易地识别一棵树,即使它是蓝色的。色彩变化不会让您的照片难以辨认。
【解决方案3】:

我修改如下。它奏效了。

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

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 2012-04-11
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多