요약하면 알고리즘은 source1, source2, hidden의 세 가지 이미지를 사용합니다. 그런 다음 숨겨진 이미지를 source1 및 source2에 숨 깁니다 (output1 및 output2 생성). output1을 output2에 배치하면 숨겨진 이미지를 볼 수 있습니다. 그러나 output2는 어떻게 든 손상되고 일반 아이디어가 작동하는 동안 숨겨진 이미지 (및 source1)를 볼 수 있습니다. (어렵지만 가능합니다)두 개의 매우 비슷한 이미지를 생성하는 동안 하나의 이미지가 손상됩니다.
http://datagenetics.com/blog/november32013/index.html에서 알고리즘을 구현하려고합니다. ("이 마술은 어떻게 작동합니까?"아래로 스크롤하여 소개를 건너 뜁니다).
편집 : setTwo 메소드가 어떻게 든 동일한 공백을 얻는다는 사실을 알 수 있습니다. blank2를 적용하고 재편성하면 문제가 해결됩니다. 그러나, 나는 여전히 동일한 데이터가 거기에 들어가는 방법을 모른다. 결국, setTwo 알고리즘을 호출하기 전에 항상 두 개의 다른 숫자를 무작위로 추출한다. 누구나 그 이유를 알 수 있을까?
EDIT2 : 인수가 같은지 테스트하기 위해 setTwo를 호출하기 전에 검사를 추가했습니다. 검사는 매번 실패하고 setTwo 내의 검사가 문제를 포착합니다. 나는 데이터가 어떻게 손상되는지 전혀 모른다. "대답을"포기하지 않는
4th image - output 2 - problems
package visualcryptography;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
/**
*
* @author Ugnius
*/
public class VisualCryptography {
BufferedImage sourceOne;
BufferedImage sourceTwo;
BufferedImage hiddenImage;
BufferedImage outputOne;
BufferedImage outputTwo;
GUI loadingBar;
static final int black = java.awt.Color.BLACK.getRGB();
static final int white = java.awt.Color.WHITE.getRGB();
static final int whiteToWrite = (new Color(255, 255, 255, 0)).getRGB();
Random r = new Random();
//Color cl;
/**
* @param args the command line arguments
*/
public VisualCryptography(BufferedImage source1, BufferedImage source2, BufferedImage hidden, GUI loadingBar) throws Exception {
if ((source1.getHeight() != source2.getHeight()) || (source2.getHeight() != hidden.getHeight())) {
throw new Exception();
}
if ((source1.getWidth() != source2.getWidth()) || (source2.getWidth() != hidden.getWidth())) {
throw new Exception();
}
sourceOne = source1;
sourceTwo = source2;
hiddenImage = hidden;
this.loadingBar = loadingBar;
//cl = java.awt.Color.WHITE;
//cl = new Color(cl.getRed(), cl.getGreen(), cl.getBlue(), 0);
//white = cl.getRGB();
//System.out.println("this is WHITE:" + cl.getRGB());
//System.out.println("this is my white:" + (new Color(0,0,0).getRGB()));
//white = 1;
//cl = new Color(255, 255, 255, 255);
//white = cl.getRGB();
//white = -1;
//white = 16777215;
//white = java.awt.Color.WHITE.getRGB();
//byte alpha = (byte) 0xff;
//int mc = (alpha << 24) | 0x00ffffff;
//white = white & mc;
//System.out.println("this is my transparent white:" + white);
//System.out.println("this is black" + black);
}
public void process() throws IOException {
int total = sourceOne.getHeight();
outputOne = new BufferedImage(sourceOne.getWidth() * 2, sourceOne.getHeight() * 2, BufferedImage.TYPE_INT_ARGB);
outputTwo = new BufferedImage(sourceTwo.getWidth() * 2, sourceTwo.getHeight() * 2, BufferedImage.TYPE_INT_ARGB);
for (int height = 0; height < sourceOne.getHeight(); height++) {
System.out.println(height + "/" + total);
//loadingBar.repaint();
for (int width = 0; width < sourceOne.getWidth(); width++) {
//Random r = new Random();
//if ((height > 87) && (width > 190)){
//System.out.println("Hello");
//}
if (hiddenImage.getRGB(width, height) != white) {
//when the hidden image pixel is BLACK
//the combined two cypgher images (OR) have to have all four subpixels set.
if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) != white)) {
//when bouth source images also have a black pixel, this is easy. Both cypher images need to have three out of
//the four subpixels set. The only constraint is that the missing subpixel is not the same on both layers.
//one pixel is randomly selected on the first layer, and one is randomly select from the other three on the
//second layer
int randomized = r.nextInt(4);
//randomized = 0; top left
//randomized = 1; top right
//randomized = 2; bottom left
//randomized = 3; bottom right
this.setThree(width, height, randomized, outputOne);
int newRandomized = r.nextInt(4);
while (randomized == newRandomized) {
newRandomized = r.nextInt(4);
}
this.setThree(width, height, newRandomized, outputTwo);
} else {
if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) == white)) {
//When the first image has a black pixel (requiring three subpixels set), and the second image
//has a white pixel (requiring two subpixels set), as above, first, a random single subpixel is
//selected on the black layer to remove. Next two subpixels are randomly selected on the second
//layer with the constraint that one of the selected subpixels is the same as the gap in the
//first layer. In this way, when the two are combined, four black subpixels are displayed.
int randomized = r.nextInt(4);
//randomized = 0; top left
//randomized = 1; top right
//randomized = 2; bottom left
//randomized = 3; bottom right
this.setThree(width, height, randomized, outputOne);
int random1 = r.nextInt(4);
while (random1 == randomized) {
random1 = r.nextInt(4);
}
int random2 = r.nextInt(4);
while ((random2 == randomized) || random1 == random2) {
random2 = r.nextInt(4);
}
this.setTwo(width, height, random1, random2, outputTwo);
} else {
if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) != white)) {
//the opposite happens when the first layer is white, and the second layer is black
int randomized = r.nextInt(4);
//randomized = 0; top left
//randomized = 1; top right
//randomized = 2; bottom left
//randomized = 3; bottom right
this.setThree(width, height, randomized, outputTwo);
int random1 = r.nextInt(4);
while (random1 == randomized) {
random1 = r.nextInt(4);
}
int random2 = r.nextInt(4);
while ((random2 == randomized) || random1 == random2) {
random2 = r.nextInt(4);
}
this.setTwo(width, height, random1, random2, outputOne);
} else {
if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) == white)) {
int randomized = r.nextInt(4);
int randomized1 = r.nextInt(4);
while (randomized == randomized1) {
randomized1 = r.nextInt(4);
}
this.setTwo(width, height, randomized, randomized1, outputOne);
int[] remaining = new int[2];
int counter = 0;
int number = 0;
while (counter != 2) {
if ((number != randomized) && (number != randomized1)) {
remaining[counter] = number;
counter++;
}
number++;
}
this.setTwo(width, height, remaining[0], remaining[1], outputTwo);
}
}
}
}
} else {
//when the hidden image pixel is WHITE
//the combined two cypher images (OR) have to have any three subpixels set
if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) != white)) {
//When both source images have a black pixel, this is easy. Both cypher images need to have
//three out of the four subpixels set, and these need to be the same subpixels. Three subpixels
//are randomly selected and these are set on both of the cypher image layers.
int random = r.nextInt(4);
this.setThree(width, height, random, outputOne);
this.setThree(width, height, random, outputTwo);
} else {
if ((sourceOne.getRGB(width, height) != white) && (sourceTwo.getRGB(width, height) == white)) {
//When the first image has a black pixel (requiring three subpixels set), and the second image
//has a white pixel (requiring two subpixels set), as above, first, three random subpixels
//are selected on the first layer. Next one of these three subpixels is randomly selected for
//removal and this pattern is used on the second layer.
int random = r.nextInt(4);
this.setThree(width, height, random, outputOne);
int random1 = r.nextInt(4);
while (random == random1) {
random1 = r.nextInt(4);
}
this.setTwo(width, height, random, random1, outputTwo);
} else {
if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) != white)) {
int random = r.nextInt(4);
this.setThree(width, height, random, outputTwo);
int random1 = r.nextInt(4);
while (random == random1) {
random1 = r.nextInt(4);
}
this.setTwo(width, height, random, random1, outputOne);
} else {
if ((sourceOne.getRGB(width, height) == white) && (sourceTwo.getRGB(width, height) == white)) {
//Finally, if both source pixels are white (requiring two subpixels set), two are selected
//at random on the first layer, then one of these is duplicated on the second layer, and a
//second random subpixel is selected on the second layer (from the two white subpixels not
//selected on the first layer). Both layers have two subpixels, and when combined, there are
//three subpixels visbile.
int random = r.nextInt(4);
//this.setThree(width, height, random, outputTwo);
int random1 = r.nextInt(4);
while (random == random1) {
random1 = r.nextInt(4);
}
this.setTwo(width, height, random, random1, outputOne);
int random2 = r.nextInt(4);
if (random2 == random) {
random2 = r.nextInt(4);
}
this.setTwo(width, height, random, random2, outputTwo);
}
}
}
}
}
}
}
}
void setThree(int x, int y, int blank, BufferedImage im) {
//blank = 0; top left
//blank = 1; top right
//blank = 2; bottom left
//blank = 3; bottom right
im.setRGB(2 * x, 2 * y, black);
im.setRGB(2 * x + 1, 2 * y, black);
im.setRGB(2 * x, 2 * y + 1, black);
im.setRGB(2 * x + 1, 2 * y + 1, black);
switch (blank) {
case 0:
im.setRGB(2 * x, 2 * y, whiteToWrite);
break;
case 1:
im.setRGB(2 * x + 1, 2 * y, whiteToWrite);
break;
case 2:
im.setRGB(2 * x, 2 * y + 1, whiteToWrite);
break;
case 3:
im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite);
break;
}
}
private void setTwo(int x, int y, int blank1, int blank2, BufferedImage im) {
//blank = 0; top left
//blank = 1; top right
//blank = 2; bottom left
//blank = 3; bottom right
im.setRGB(2 * x, 2 * y, black);
im.setRGB(2 * x + 1, 2 * y, black);
im.setRGB(2 * x, 2 * y + 1, black);
im.setRGB(2 * x + 1, 2 * y + 1, black);
switch (blank1) {
case 0:
im.setRGB(2 * x, 2 * y, whiteToWrite);
break;
case 1:
im.setRGB(2 * x + 1, 2 * y, whiteToWrite);
break;
case 2:
im.setRGB(2 * x, 2 * y + 1, whiteToWrite);
break;
case 3:
im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite);
break;
}
switch (blank2) {
case 0:
im.setRGB(2 * x, 2 * y, whiteToWrite);
break;
case 1:
im.setRGB(2 * x + 1, 2 * y, whiteToWrite);
break;
case 2:
im.setRGB(2 * x, 2 * y + 1, whiteToWrite);
break;
case 3:
im.setRGB(2 * x + 1, 2 * y + 1, whiteToWrite);
break;
}
}
public BufferedImage[] getOutput() {
BufferedImage[] output = new BufferedImage[2];
output[0] = outputOne;
output[1] = outputTwo;
return output;
}
}