(See the next iteration.)
I have that application for en-/decrypting files. Here, I will post the actual GUI and command line code. In order to run the program refer to this GitHub repository.
Some images:
My code is as follows:
App.java:
package net.coderodde.ciphertool;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import net.coderodde.encryption.CipherTools;
import net.coderodde.file.FileTools;
/**
* This class implements the command line app for encrypting and decrypting
* files with a key.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 29, 2016)
*/
public class App {
private static final String HELP_MESSAGE =
"Usage: java -jar File.jar [-e | -d <key> FILE1 [FILE2 [...]]]\n" +
"Where -e encrypt the files.\n" +
" -d decrypt the files.\n" +
" <key> the key in decimal; " +
"use prefix \"0x\" for hexadecimal.\n" +
"If you omit all arguments a GUI is started instead.";
private boolean graphicalInterfaceRequested;
private boolean printHelpMessage;
private Mode mode;
private int key;
private String[] args;
public void processArguments(String[] args) {
this.args = args.clone();
if (args.length == 0) {
graphicalInterfaceRequested = true;
return;
}
if (args.length < 3) {
printHelpMessage = true;
return;
}
switch (args[0]) {
case "-e":
mode = Mode.ENCRYPTING;
break;
case "-d":
mode = Mode.DECRYPTING;
break;
}
if (mode == null) {
printHelpMessage = true;
return;
}
if (args[1].length() >= 2 &&
(args[1].startsWith("0x") || args[1].startsWith("0X"))) {
String keyString = args[1].substring(2).trim().toLowerCase();
try {
key = Integer.parseInt(keyString, 16);
} catch (NumberFormatException ex) {
printHelpMessage = true;
return;
}
} else {
try {
key = Integer.parseInt(args[1]);
} catch (NumberFormatException ex) {
printHelpMessage = true;
return;
}
}
}
public boolean helpMessageRequested() {
return printHelpMessage;
}
public void exec() {
if (graphicalInterfaceRequested) {
SwingUtilities.invokeLater(() -> { execAsGUI(); });
} else {
execAsCommandLine();
}
}
private void execAsGUI() {
JFrame frame = new JFrame("File cipher tool");
JButton buttonEncrypt = new JButton("Encrypt");
JButton buttonDecrypt = new JButton("Decrypt");
buttonEncrypt.setPreferredSize(new Dimension(200, 40));
buttonDecrypt.setPreferredSize(new Dimension(200, 40));
buttonEncrypt.addActionListener(
new MyActionListener(frame, Mode.ENCRYPTING));
buttonDecrypt.addActionListener(
new MyActionListener(frame, Mode.DECRYPTING));
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(buttonEncrypt, BorderLayout.NORTH);
frame.getContentPane().add(buttonDecrypt, BorderLayout.SOUTH);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
moveToCenter(frame);
frame.setVisible(true);
}
private static void moveToCenter(JFrame frame) {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((screen.width - frame.getWidth()) >> 1,
(screen.height - frame.getHeight()) >> 1);
}
private void execAsCommandLine() {
List<File> fileList = getFileList(args);
switch (mode) {
case ENCRYPTING:
encryptAll(fileList, key);
break;
case DECRYPTING:
decryptAll(fileList, key);
break;
}
}
static void encryptAll(List<File> fileList, int key) {
fileList.stream().forEach((File file) -> {
try {
byte[] data = FileTools.readFile(file);
byte[] encryptedData = CipherTools.encrypt(data, key);
FileTools.writeFile(file, encryptedData);
} catch (IOException ex) {
System.err.println("ERROR: " + ex.getMessage());
}
});
}
static void decryptAll(List<File> fileList, int key) {
fileList.stream().forEach((File file) -> {
try {
byte[] data = FileTools.readFile(file);
byte[] decryptedData = CipherTools.decrypt(data, key);
FileTools.writeFile(file, decryptedData);
} catch (IOException ex) {
System.err.println("ERROR: " + ex.getMessage());
}
});
}
private List<File> getFileList(String[] args) {
// We subtract 2 in order to omit the fist two arguments in 'args' that
// are the switch and the key.
List<File> fileList = new ArrayList<>(args.length - 2);
for (int i = 2; i < args.length; ++i) {
fileList.add(new File(args[i]));
}
return fileList;
}
private String getHelpMessage() {
return HELP_MESSAGE;
}
public static void main(String[] args) throws IOException {
try {
App app = new App();
app.processArguments(args);
if (app.helpMessageRequested()) {
System.out.println(app.getHelpMessage());
System.exit(0);
}
app.exec();
} catch (RuntimeException ex) {
System.err.println("ERROR: " + ex.getMessage());
System.exit(1);
}
}
}
MyActionListener.java:
package net.coderodde.ciphertool;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Arrays;
import java.util.Objects;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import static net.coderodde.ciphertool.App.decryptAll;
import static net.coderodde.ciphertool.App.encryptAll;
/**
* This class implements the action listener for the GUI buttons.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Mar 1, 2016)
*/
final class MyActionListener implements ActionListener {
private final JFrame ownerFrame;
private final Mode mode;
MyActionListener(JFrame ownerFrame, Mode mode) {
this.mode = Objects.requireNonNull(mode, "The input mode is null.");
this.ownerFrame = ownerFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
File[] files = askUserToChooseFiles(mode == Mode.ENCRYPTING ?
"Choose files to encrypt" :
"Choose files to decrypt",
ownerFrame);
if (files == null) {
return;
}
String keyString = JOptionPane.showInputDialog(
ownerFrame,
mode == Mode.ENCRYPTING ?
"Type in the encryption key:" :
"Type in the decryption key:",
"",
JOptionPane.QUESTION_MESSAGE);
if (keyString == null || keyString.isEmpty()) {
// User cancelled the entry of the key.
return;
}
if (keyString.length() >= 2
&& (keyString.startsWith("0x")
|| keyString.startsWith("0X"))) {
String keyStringPrepared = keyString.substring(2)
.trim()
.toLowerCase();
try {
int key = Integer.parseInt(keyStringPrepared, 16);
switch (mode) {
case ENCRYPTING:
encryptAll(Arrays.asList(files), key);
break;
case DECRYPTING:
decryptAll(Arrays.asList(files), key);
break;
default:
throw new IllegalStateException(
"Should never get here.");
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(
ownerFrame,
"\"" + keyString + "\" is an invalid key.",
"",
JOptionPane.ERROR_MESSAGE);
}
} else {
try {
int key = Integer.parseInt(keyString);
switch (mode) {
case ENCRYPTING:
encryptAll(Arrays.asList(files), key);
break;
case DECRYPTING:
decryptAll(Arrays.asList(files), key);
break;
default:
throw new IllegalStateException(
"Should never get here.");
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(
ownerFrame,
"\"" + keyString + "\" is an invalid key.",
"",
JOptionPane.ERROR_MESSAGE);
}
}
}
private File[] askUserToChooseFiles(String title, JFrame ownerFrame) {
JFileChooser chooser = new JFileChooser(title);
chooser.setMultiSelectionEnabled(true);
int status = chooser.showOpenDialog(ownerFrame);
if (status == JFileChooser.APPROVE_OPTION) {
return chooser.getSelectedFiles();
}
return null;
}
}
Mode.java:
package net.coderodde.ciphertool;
/**
* The enumeration enumerates the function modes of the program.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Mar 1, 2016)
*/
enum Mode {
ENCRYPTING,
DECRYPTING,
}
Please, tell me anything that comes to mind.