Skip to content

Instantly share code, notes, and snippets.

@porthunt
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porthunt/111f0dd0320045ac296a to your computer and use it in GitHub Desktop.
Save porthunt/111f0dd0320045ac296a to your computer and use it in GitHub Desktop.
/* Developed by: Joao Pedro Portela Gomez Vaz */
/* COMPLETE - Ver. 1.5 */
import java.io.*;
import java.security.*;
import java.util.*;
/* HOW TO RUN */
// 1. cd /your/directory
// 2. javac DigestCalculator.java
// 3. java DigestCalculator digestType "/path/to/ArqListaDigest.txt" "/path/to/Arq1.png" "/path/to/Arq2.jpg"
// Example:
// javac MD5 "ArqListaDigest.txt" "DigestCalculator.java"
// java DigestCalculator SHA1 "ArqListaDigest.txt" "DigestCalculator.java" "metadata.db" "DigestCalculator.class"
/* END OF HOW TO RUN */
public class DigestCalculator {
public static void main(String[] args) {
if (args.length < 3) {
closeProgram(1);
} else {
List<String> argList = Arrays.asList(args);
List<String> files = argList.subList(2, argList.size());
String listFilePath = argList.get(1);
String digestType = argList.get(0);
System.out.println(listFilePath);
List<FileData> fileData = createFileData(listFilePath);
//check if all the files are correct.
checkFiles(files);
checkList(listFilePath);
for (String filePath : files) {
try {
String listDigest = "";
byte[] plainText = getBytesFromFile(new File(filePath));
StringBuffer digestArgs = createDigest(plainText, digestType);
FileData file = new FileData();
String[] pathParts = filePath.split("/");
String fileName = pathParts[pathParts.length-1];
if(containsKey(fileData, fileName)) {
for(int i=0; i < fileData.size(); i++) {
if (fileData.get(i).getFileName().equals(fileName))
file = fileData.get(i);
}
if(file.getDigestType1().equals(digestType) || file.getDigestType2().equals(digestType)) {
if (file.getDigest1().equals(digestArgs.toString()) || file.getDigest2().equals(digestArgs.toString()))
System.out.println(fileName+" "+digestType+" "+digestArgs+" (OK)");
else
System.out.println(fileName+" "+digestType+" "+digestArgs+" (NOT OK)");
}
else {
if(isCollision(fileData, digestType, digestArgs.toString()))
System.out.println(fileName+" "+digestType+" "+digestArgs.toString()+" (COLLISION)");
else {
System.out.println(fileName+" "+digestType+" "+digestArgs.toString()+" (NOT FOUND)");
file.setDigestType2(digestType);
file.setDigest2(digestArgs.toString());
editList(file, listFilePath);
fileData.add(new FileData(fileName, digestType, digestArgs.toString(), "", ""));
}
}
} else {
if(isCollision(fileData, digestType, digestArgs.toString()))
System.out.println(fileName+" "+digestType+" "+digestArgs.toString()+" (COLLISION)");
else {
System.out.println(fileName+" "+digestType+" "+digestArgs.toString()+" (NOT FOUND)");
FileData newFile = new FileData(fileName, digestType, digestArgs.toString(), "", "");
addToList(newFile, listFilePath);
fileData.add(newFile);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
/* Verify if the file paths are correct */
public static boolean checkFiles(List<String> files) {
for(String filePath : files) {
File file = new File(filePath);
if(!file.isFile())
closeProgram(2);
}
return true;
}
/* Verify if the list is correct */
public static boolean checkList(String lst) {
File file = new File(lst);
if(!file.isFile())
closeProgram(3);
return true;
}
/* All the errors are here. */
public static void closeProgram(int errNum) {
switch (errNum) {
case 1: System.out.println("Error 001. How to use: java DigestCalculator DigestType \"ArqListDigest.txt\" \"FileName1.xxx\" \"FileName2.xxx\" \"FileNameN.xxx\"");
break;
case 2: System.out.println("Error 002. One of the files was not founded.");
break;
case 3: System.out.println("Error 003. The digests list doesn't exists.");
break;
}
System.out.println("Aborting program...");
System.exit(1);
}
/*************************************************/
/* Method name: isCollision
/* Parameters: digestType, digest, digestMap
/* Function: check if the digest exists in the list with another name.
/* Return: true or false.
/*************************************************/
public static boolean isCollision(List<FileData> fileData, String digestType, String digest) throws Exception {
for (int i=0; i < fileData.size(); i++) {
if (fileData.get(i).getDigestType1().equals(digestType) || fileData.get(i).getDigestType2().equals(digestType)) {
if (fileData.get(i).getDigest1().equals(digest) || fileData.get(i).getDigest2().equals(digest)) {
return true;
}
}
}
return false;
}
/* End of isCollision */
/*************************************************/
/* Method name: createDigest
/* Parameters: plainText
/* Function: create the digest of the file.
/* Return: a StringBuffer with the digest.
/*************************************************/
public static StringBuffer createDigest(byte[] plainText, String type) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(type);
messageDigest.update(plainText);
byte [] digest = messageDigest.digest();
StringBuffer buf = new StringBuffer();
for(int i = 0; i < digest.length; i++) {
String hex = Integer.toHexString(0x0100 + (digest[i] & 0x00FF)).substring(1);
buf.append((hex.length() < 2 ? "0" : "") + hex);
}
return buf;
}
/* End of createDigest */
/*************************************************/
/* Method name: addToList
/* Parameters: fileName, digestType, digest
/* Function: add the row to the list.
/* Return: void
/*************************************************/
public static void addToList(FileData fileData, String filePath) {
String[] pathParts = filePath.split("/");
String fileNameList = pathParts[pathParts.length-1];
try
{
FileWriter fw = new FileWriter(fileNameList, true);
fw.write(fileData.getFileName()+" "+fileData.getDigestType1()+" "+fileData.getDigest1()+"\n");//appends the string to the file
fw.close();
} catch(IOException e) {
System.err.println("IOException: " + e.getMessage());
}
}
/* End of addToList */
/*************************************************/
/* Method name: editList
/* Parameters: fileName, digestType, digest
/* Function: add the row to the list.
/* Return: void
/*************************************************/
public static void editList(FileData fileData, String filePath) {
try {
File inputFile = new File(filePath);
File tempFile = new File("myTempFile.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String lineToRemove = fileData.getFileName()+" "+fileData.getDigestType1()+" "+fileData.getDigest1();
String currentLine;
while((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)){
continue;
}
writer.write(currentLine+"\n");
}
writer.write(lineToRemove+"[ "+fileData.getDigestType2()+" "+fileData.getDigest2()+" ]\n");
inputFile.delete();
tempFile.renameTo(new File(filePath));
reader.close();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/* End of addToList */
/*************************************************/
/* Method name: containsKey
/* Parameters: fileData, fileName
/* Function: Check if the file exists in the list.
/* Return: boolean
/*************************************************/
public static boolean containsKey(List<FileData> fileData, String fileName) {
for (int i=0; i<fileData.size(); i++) {
if(fileData.get(i).getFileName().equals(fileName)) {
return true;
}
}
return false;
}
/* End of containsKey */
/* Supporting function: convert a File to byte[]. */
@SuppressWarnings("resource")
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
/* Supporting function: create a HashMap based on a file. */
private static List<FileData> createFileData(String fileName) {
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
String buffer;
List<FileData> listData = new ArrayList<FileData>();
while ((buffer = in.readLine()) != null) {
String[] line = buffer.split(" ");
FileData file;
if (line[2].substring(line[2].length()-1, line[2].length()).equals("[")) {
file = new FileData(line[0], line[1], line[2].substring(0, line[2].length()-1), line[3], line[4]);
} else {
file = new FileData(line[0], line[1], line[2], "", "");
}
listData.add(file);
}
in.close();
return listData;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
// CLASS: FileData.java
public class FileData {
private String fileName;
private String digestType1;
private String digest1;
private String digestType2;
private String digest2;
public FileData(String fileName, String digestType1, String digest1,
String digestType2, String digest2) {
super();
this.fileName = fileName;
this.digestType1 = digestType1;
this.digest1 = digest1;
this.digestType2 = digestType2;
this.digest2 = digest2;
}
public FileData() {
}
public String getFileName() {
return fileName;
}
public String getDigestType1() {
return digestType1;
}
public String getDigest1() {
return digest1;
}
public String getDigestType2() {
return digestType2;
}
public String getDigest2() {
return digest2;
}
public void setDigestType2(String digestType2) {
this.digestType2 = digestType2;
}
public void setDigest2(String digest2) {
this.digest2 = digest2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment