图像加密,为什么无法解密?

9
我正在尝试使用ACM和Henon加密图像,加密成功了,但是无法解密。问题在于(解密问题在XOR像素值之后,它无法将其还原到初始位置)。
加密方案如下: http://ieeexplore.ieee.org/xpl/articleDetails.jsp?tp=&arnumber=5054653&contentType=Conference+Publications&queryText%3Dimage+encryption+henon 加密步骤如下:
1.读取图像 2.像素提取 3.使用ACM混淆像素 4.生成Henon伪随机序列 5.四舍五入Henon伪随机序列 6.使用Henon伪随机序列与混淆像素值进行异或操作 7.写入图像 8.完成加密图像
解密步骤如下:
1.读取加密图像 2.像素提取 3.生成Henon伪随机序列 4.四舍五入Henon伪随机序列 5.使用Henon伪随机序列与混淆像素值进行异或操作 6.使用逆ACM还原像素位置 7.写入图像 8.图像已恢复原状
谢谢。以下是加密代码:
  img = ImageIO.read(new File("5x5grayscale.bmp"));    
  Raster pixel = img.getData();               
  pxl = new int[img.getWidth()][img.getHeight()];
  pxl2 = new int[img.getWidth()][img.getHeight()];           

  for(int j=0;j<img.getHeight();j++){ 
    for(int i=0;i<img.getWidth();i++){                 
      pxl[i][j]= pixel.getSample(i, j, 0);  
      pxl2[i][j]= pixel.getSample(i, j, 0);  
    }                                                                       
  }           

  // shuffe pixel ACM iterration 1
  System.out.println("shuffle iteration  1");
  for(int i=0;i<5;i++){
    for(int j=0;j<5;j++){                 
      x[xx]=(1*i + c*j)%5;            
      y[xx]=(d*i + e*j)%5; 
      //System.out.println("-new coordinate ="+i+" , "+j+"="+x[xx]+","+y[xx]);
      xx++; 
    }
  }

  //shuffle pixel ACM 2 sd 10
  for(int k=0;k<9;k++){
    System.out.println("shuffle iteration "+(k+2));
    xx=0; 
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++){                 
        xtemp = x[xx];
        ytemp = y[xx];
        x[xx] = (1*xtemp + c*ytemp) % 5;
        y[xx] = (d*xtemp + e*ytemp) % 5;   

        System.out.println("-new coordinate="+i+" , "+j+"="+x[xx]+","+y[xx]);
        xx++; 
      }
    }              
  } 

  xx=0; 
  for (int a =0;a<5;a++){
    for(int b=0;b<5;b++){
      pxl[a][b]= pxl2[x[xx]][y[xx]];
      xx++;
      //System.out.println(pxl[a][b]);
    }
  }

  System.out.println("===================================henon============================");
  double k[] = new  double[102]; 
  int inter[] = new int [102];

  k[0] = 0.01;
  k[1] = 0.02; 
  double a=1.4;
  double b=0.3;


  System.out.println("generate pseudo random");
  for(int i=0;i<100;i++){                       
    k[i+2] =1-a*(Math.pow(k[i+1], 2))+b*k[i];
    // System.out.println(k[i]);            
  }  

  System.out.println("after rounded");
  for(int i=0;i<100;i++){
    inter[i]= (int) Math.round((k[i]*65536)%256);
    if(inter[i]<0){
      inter[i]=inter[i]+256;
    }
    //    System.out.println(inter[i]);
  }

  System.out.println("setelah xor");
  System.out.println("setelah xor");
  cipher = new int[img.getWidth()][img.getHeight()];
  int z=0;  
  for(int ii=0;ii<img.getWidth();ii++){
    for(int jj=0;jj<img.getHeight();jj++){
      cipher[ii][jj]=inter[z]^pxl[ii][jj];
      // System.out.println(cipher[ii][jj]);
      z++;
    }
  }

  image = new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_BYTE_GRAY);          
  WritableRaster write = image.getRaster();                 

  for(int ii=0;ii<img.getHeight();ii++){
    for(int jj=0;jj<img.getWidth();jj++){          
      write.setSample(jj, ii, 0,cipher[jj][ii] );   
    }  
  }  

  ImageIO.write(image, "bmp", new File("acmhenonenkrip5x5.bmp"));  
  System.out.println("cipher image done");           
} 

以下是解密代码:

public static void main (String[] args) throws java.lang.Exception
{
  int c =2;
  int d = 2;
  int e = c*d+1;
  int x[]= new int[100];
  int y[]= new int[100];
  int xx=0;
  int xtemp;
  int ytemp;
  int sama=1;
  BufferedImage img ;
  BufferedImage image = null;
  int [][]pxl = null ;
  int [][]pxl2 = null ;
  int [][]cipher=null;

  img = ImageIO.read(new File("acmhenonenkrip5x5.bmp"));    
  Raster pixel = img.getData();     

  pxl = new int[img.getWidth()][img.getHeight()];
  pxl2 = new int[img.getWidth()][img.getHeight()];


  for(int j=0;j<img.getHeight();j++){ 
    for(int i=0;i<img.getWidth();i++){                 
      pxl[i][j]= pixel.getSample(i, j, 0);  
      pxl2[i][j]= pixel.getSample(i, j, 0);  
    }                                                                       
  }   

  System.out.println("===================================henon============================");
  double k[] = new  double[30];            int inter[] = new int [30];

  k[0] = 0.01;
  k[1] = 0.02; 
  double a=1.4;
  double b=0.3;


  System.out.println("generate pseudo random");
  for(int i=0;i<27;i++){                       
    k[i+2] =1-a*(Math.pow(k[i+1], 2))+b*k[i];
    // System.out.println(k[i]);            
  }  

  System.out.println("after rounded");
  for(int i=0;i<27;i++){
    inter[i]= (int) Math.round((k[i]*65536)%256);
    if(inter[i]<0){
      inter[i]=inter[i]+256;
    }
    // System.out.println(inter[i]);
  }

  System.out.println("after  xor");
  cipher = new int[img.getWidth()][img.getHeight()];
  int z=0;  
  for(int ii=0;ii<img.getWidth();ii++){
    for(int jj=0;jj<img.getHeight();jj++){
      cipher[ii][jj]=inter[z]^pxl[ii][jj];
      // System.out.println(cipher[ii][jj]);
      z++;
    }
  }

  System.out.println("===================================inverseacm============================");

  System.out.println("decrypt iteration1");

  for(int i=0;i<5;i++){
    for(int j=0;j<5;j++){      
      x[xx]=((e*i) + (-c*j))%5; 
      if(x[xx]<0){
        x[xx]=x[xx]+5;
      }
      y[xx]=((-d*i) + (1*j))%5;  
      if(y[xx]<0){
        y[xx]=y[xx]+5;
      }
      // System.out.println(xx+"-new coordinate ="+i+","+j+"="+x[xx]+","+y[xx]);
      xx++; 
    }    
  }

  for(int iter=0;iter<9;iter++){
    System.out.println("decrypt iteration "+(iter+2));
    xx=0;  
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++){     
        xtemp = x[xx];
        ytemp = y[xx];
        x[xx]=((e*xtemp) + (-c*ytemp))%5; 
        if(x[xx]<0){
            x[xx]=x[xx]+5;
        }
        y[xx]=((-d*xtemp) + (1*ytemp))%5;  
        if(y[xx]<0){
          y[xx]=y[xx]+5;
        }
        // System.out.println(xx+"-new coordinate ="+i+","+j+"="+x[xx]+","+y[xx]);
        xx++; 
      }          
    }
  }    

  xx=0; 
  for(int ii=0;ii<img.getWidth();ii++){
    for(int jj=0;jj<img.getHeight();jj++){
      System.out.println("cip"+cipher[x[xx]][y[xx]]); //tracing pixel value of cipher
      xx++;     
    }            
  } 

  xx=0; 
  for(int ii=0;ii<img.getWidth();ii++){
    for(int jj=0;jj<img.getHeight();jj++){
      System.out.println("pxl"+pxl[x[xx]][y[xx]]); //tracing pixel value of pxl
      xx++;     
    }
  }

  image = new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_BYTE_GRAY);          
  WritableRaster write = image.getRaster();                 

  for(int ii=0;ii<img.getHeight();ii++){
    for(int jj=0;jj<img.getWidth();jj++){          
      write.setSample(jj, ii, 0,cipher[jj][ii] );                             
    }  
  }  

  ImageIO.write(image, "bmp", new File("acmhenondekrip5x5.bmp"));  
}

你也许是在参考这篇论文吗?http://dl.acm.org/citation.cfm?id=1917638 你使用它(而不是像RC4之类的东西)是出于好奇,还是其他原因? - Matt Sieker
6
你为什么使用这样奇怪的加密方案? - CodesInChaos
1
我已经添加了参考文献。 - user1552917
1
你的洗牌代码只影响了主对角线,我可能误解了你的意思,但在我看来它似乎有问题。 - lynks
你能提供加密程序的前几行吗? - 101100
5
你有检查过在这里开始出现的差异吗?如果你比较所节省的字节,它们与你读取的那些是相同的吗?反转后的ACM与之前的ACM相同吗?反转XOR后的值与原始XOR前的值相同吗?如果你硬编码期望的反转ACM,算法的其余部分是否正常工作?如果你能确定是哪一部分出了问题,这可能会有所帮助。 - Roger Lindsjö
1个回答

1
你应该将每个阶段分成两个方法:一个用于执行,另一个用于撤销。然后,你应该编写一组简短的测试,生成成千上万个随机输入,并且对每个输入进行检查 input.equals(undoIt(doIt(input))) 或类似的操作。
如果任何测试失败,你就会知道从哪里开始查找问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接