Java tutorial
/* This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://www.wtfpl.net/ for more details. */ package org.crazyt.xgogdownloader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.io.FilenameUtils; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.Text; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; // Create GOG XML public class Util { public final String makeFilepath(String directory, String path, String gamename, String subdirectory) { String filepath; if (gamename == "") { if (path.charAt(0) == '/') { String tmp_path = path.substring(1, path.length()); filepath = directory + tmp_path; } else { filepath = directory + path; } } else { String filename = path.substring(path.lastIndexOf("/") + 1, path.length()); if (!subdirectory.isEmpty()) { subdirectory = File.separatorChar + subdirectory; } filepath = directory + File.separatorChar + gamename + subdirectory + File.separatorChar + filename; } return filepath; } public final String getFileHash(String filename) { try { MessageDigest digest = MessageDigest.getInstance("MD5"); FileInputStream fis = new FileInputStream(filename); byte[] dataBytes = new byte[1024]; int nread = 0; while ((nread = fis.read(dataBytes)) != -1) { digest.update(dataBytes, 0, nread); } byte[] mdbytes = digest.digest(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < mdbytes.length; i++) { sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); } String result = sb.toString(); return result; } catch (NoSuchAlgorithmException e) { System.out.println(e); return ""; } catch (FileNotFoundException e) { System.out.println(e); return ""; } catch (IOException e) { System.out.println(e); return ""; } } public final String getChunkHash(String chunk) { try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(chunk.getBytes()); byte[] mdbytes = md.digest(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < mdbytes.length; i++) { sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); } String result = sb.toString(); return result; } catch (NoSuchAlgorithmException e) { System.out.println(e); return ""; } } public final int createXML(String filepath, int chunk_size, String xml_dir) { int res = 0; File infile; int filesize; int size; int chunks; int i; if (xml_dir == "") { xml_dir = ".cache/xgogdownloader/xml"; } // end of if File path = Factory.newFile(xml_dir); if (!path.exists()) { if (!path.mkdirs()) { System.out.println("Failed to create directory: " + path); } } infile = Factory.newFile(filepath); // RandomAccessFile file = new RandomAccessFile("file.txt", "rw");? // fseek/seek ftell/getFilePointer rewind/seek(0) if (infile.exists()) { filesize = (int) infile.length(); } else { System.out.println(filepath + " doesn't exist"); return res; } // end of if-else // Get filename String filename = FilenameUtils.removeExtension(infile.getName()); String filenameXML = xml_dir + "/" + filename + ".xml"; System.out.println(filename); // Determine number of chunks int remaining = filesize % chunk_size; chunks = (remaining == 0) ? filesize / chunk_size : (filesize / chunk_size) + 1; System.out.println("Filesize: " + filesize + " bytes"); System.out.println("Chunks: " + chunks); System.out.println("Chunk size: " + (chunk_size / Math.pow(2.0, 20.0)) + " MB"); Util util_md5 = new Util(); String file_md5 = util_md5.getFileHash(filepath); System.out.println("MD5: " + file_md5); Element fileElem = new Element("file"); fileElem.setAttribute(new Attribute("name", filename)); fileElem.setAttribute(new Attribute("md5", file_md5)); fileElem.setAttribute(new Attribute("chunks", String.valueOf(chunks))); fileElem.setAttribute(new Attribute("total_size", String.valueOf(filesize))); System.out.println("Getting MD5 for chunks"); for (i = 0; i < chunks; i++) { int range_begin = i * chunk_size; // fseek(infile, range_begin, SEEK_SET); if ((i == chunks - 1) && (remaining != 0)) { chunk_size = remaining; } int range_end = range_begin + chunk_size - 1; String chunk = String.valueOf(chunk_size * 4); String hash = util_md5.getChunkHash(chunk); // calculates hash of // chunk string? Element chunkElem = new Element("chunk"); chunkElem.setAttribute(new Attribute("id", String.valueOf(i))); chunkElem.setAttribute(new Attribute("from", String.valueOf(range_begin))); chunkElem.setAttribute(new Attribute("to", String.valueOf(range_begin))); chunkElem.setAttribute(new Attribute("method", "md5")); chunkElem.addContent(new Text(hash)); fileElem.addContent(chunkElem); System.out.println("Chunks hashed " + (i + 1) + " / " + chunks + "\r"); } Document doc = new Document(fileElem); System.out.println("Writing XML: " + filenameXML); try { XMLOutputter xmlOutput = new XMLOutputter(); xmlOutput.setFormat(Format.getPrettyFormat()); xmlOutput.output(doc, Factory.newFileWriter(filenameXML)); res = 1; } catch (IOException e) { System.out.println("Can't create " + filenameXML); return res; } return res; } }