package danix.steg;
//Author: danix
//Digital steganographer
//Encrypts and decrypts png images
//To encrypt run java -jar Steg.jar [base] [image to hide] [output]
//To decrypt run java -jar Steg.jar [encrypted] [decrypted output]
//Works with pngs
//I give you the permission to run, edit and distribute this program
//and source code if you maintain the author tag
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class Steg {
//Arguments:
//3 arguments encryption: base image, secret image, encrypted filename
public static void main(String[] args) {
try {
switch (args.length) {
case 3:
encrypt(args);
break;
case 2:
decrypt(args);
break;
default:
System.out.println("Argument error");
System.out.println("Encryption: java -jar Steg.jar [base] [image to hide] [output]");
System.out.println("Decryption: java -jar Steg.jar [encrypted] [decrypted output]");
}
} catch (IOException iox) {
System.out.println(iox.getMessage());
iox.printStackTrace(System.out);
}
}
//Hides in a pixel of the original image a pixel from the hidden image
private static int doMask(int input, int cover) {
int mask = 0xc0c0c0c0;
cover &= mask;
cover >>>= 6;
input &= ~(mask >>> 6);
return input |= cover;
}
//Extracts the pixel corresponding to the hidden image in the encrypted image
private static int extractHiddenPixel(int encrypted) {
int mask = 0x03030303;
encrypted &= mask;
encrypted <<= 6;
for (int i=0; i<3; i++)
encrypted |= (encrypted >>> 2);
return encrypted;
}
//Writes a hidden image over a base image using digital steganography
private static void encrypt(String[] args) throws IOException {
String base = args[0];
String hidden = args[1];
String output = args[2];
BufferedImage inputImage = ImageIO.read(new File(base));
BufferedImage hiddenImage = ImageIO.read(new File(hidden));
if (!( (inputImage.getWidth() == hiddenImage.getWidth()) &&
(inputImage.getHeight() == hiddenImage.getHeight()))) {
System.out.println("Error: hidden image must have the same size as the input image!");
System.exit(1);
}
int width = inputImage.getWidth();
int height = inputImage.getHeight();
for (int i=0; i<width; i++) {
for (int j=0; j<height; j++) {
int inputPixel = inputImage.getRGB(i, j);
int hiddenPixel = hiddenImage.getRGB(i, j);
inputPixel = doMask(inputPixel, hiddenPixel);
inputImage.setRGB(i, j, inputPixel);
}
}
if(!ImageIO.write(inputImage, "png", new File(output)))
System.out.println("Failed writing :(");
}
//Reverts the process
private static void decrypt(String[] args) throws IOException {
String encrypted = args[0];
String decrypted = args[1];
BufferedImage encryptedImage = ImageIO.read(new File(encrypted));
int width = encryptedImage.getWidth();
int height = encryptedImage.getHeight();
for (int i=0; i<width;i++) {
for (int j=0; j<height; j++) {
int encryptedPixel = encryptedImage.getRGB(i,j);
int decryptedPixel = extractHiddenPixel(encryptedPixel);
encryptedImage.setRGB(i, j, decryptedPixel);
}
}
ImageIO.write(encryptedImage, "png", new File(decrypted));
}
}