How to reverse MD5 to get the original string? [duplicate] - md5

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to decrypt md5 hashes?
Is it possible to get a string from MD5 in Java?
Firstly a string is converted to MD5 checksum, is it possible to get this MD5 checksum back to the original text?
I'm assuming you use MessageDigest, any help is greatly appreciated, even other java libraries.
Just want to also point out on if it not possible how this app is able to it: https://play.google.com/store/apps/details?id=com.fab.md5&hl=en
I even converted some text to MD5 checksum using another application and used this checksum to see if the app was able to convert it back to text and it did.

No, that's not really possible, as
there can be more than one string giving the same MD5
it was designed to be hard to "reverse"
The goal of the MD5 and its family of hashing functions is
to get short "extracts" from long string
to make it hard to guess where they come from
to make it hard to find collisions, that is other words having the same hash (which is a very similar exigence as the second one)
Think that you can get the MD5 of any string, even very long. And the MD5 is only 16 bytes long (32 if you write it in hexa to store or distribute it more easily). If you could reverse them, you'd have a magical compacting scheme.
This being said, as there aren't so many short strings (passwords...) used in the world, you can test them from a dictionary (that's called "brute force attack") or even google for your MD5. If the word is common and wasn't salted, you have a reasonable chance to succeed...

Its not possible thats the whole point of hashing. You can however bruteforce by going through all possibilities (using all possible digits characters in every possible order) and hashing them and checking for a collision.
for more information on hashing and MD5 etc see: http://en.wikipedia.org/wiki/MD5 , http://en.wikipedia.org/wiki/Hash_function , http://en.wikipedia.org/wiki/Cryptographic_hash_function and http://onin.com/hhh/hhhexpl.html
I myself created my own app to do this, its open source you can check the link: http://sourceforge.net/projects/jpassrecovery/ and of course the source. Here is the source for easy access it has a basic implementation in the comments:
Bruter.java:
import java.util.ArrayList;
public class Bruter {
public ArrayList<String> characters = new ArrayList<>();
public boolean found = false;
public int maxLength;
public int minLength;
public int count;
long starttime, endtime;
public int minutes, seconds, hours, days;
public char[] specialCharacters = {'~', '`', '!', '#', '#', '$', '%', '^',
'&', '*', '(', ')', '_', '-', '+', '=', '{', '}', '[', ']', '|', '\\',
';', ':', '\'', '"', '<', '.', ',', '>', '/', '?', ' '};
public boolean done = false;
public boolean paused = false;
public boolean isFound() {
return found;
}
public void setPaused(boolean paused) {
this.paused = paused;
}
public boolean isPaused() {
return paused;
}
public void setFound(boolean found) {
this.found = found;
}
public synchronized void setEndtime(long endtime) {
this.endtime = endtime;
}
public int getCounter() {
return count;
}
public long getRemainder() {
return getNumberOfPossibilities() - count;
}
public long getNumberOfPossibilities() {
long possibilities = 0;
for (int i = minLength; i <= maxLength; i++) {
possibilities += (long) Math.pow(characters.size(), i);
}
return possibilities;
}
public void addExtendedSet() {
for (char c = (char) 0; c <= (char) 31; c++) {
characters.add(String.valueOf(c));
}
}
public void addStandardCharacterSet() {
for (char c = (char) 32; c <= (char) 127; c++) {
characters.add(String.valueOf(c));
}
}
public void addLowerCaseLetters() {
for (char c = 'a'; c <= 'z'; c++) {
characters.add(String.valueOf(c));
}
}
public void addDigits() {
for (int c = 0; c <= 9; c++) {
characters.add(String.valueOf(c));
}
}
public void addUpperCaseLetters() {
for (char c = 'A'; c <= 'Z'; c++) {
characters.add(String.valueOf(c));
}
}
public void addSpecialCharacters() {
for (char c : specialCharacters) {
characters.add(String.valueOf(c));
}
}
public void setMaxLength(int i) {
maxLength = i;
}
public void setMinLength(int i) {
minLength = i;
}
public int getPerSecond() {
int i;
try {
i = (int) (getCounter() / calculateTimeDifference());
} catch (Exception ex) {
return 0;
}
return i;
}
public String calculateTimeElapsed() {
long timeTaken = calculateTimeDifference();
seconds = (int) timeTaken;
if (seconds > 60) {
minutes = (int) (seconds / 60);
if (minutes * 60 > seconds) {
minutes = minutes - 1;
}
if (minutes > 60) {
hours = (int) minutes / 60;
if (hours * 60 > minutes) {
hours = hours - 1;
}
}
if (hours > 24) {
days = (int) hours / 24;
if (days * 24 > hours) {
days = days - 1;
}
}
seconds -= (minutes * 60);
minutes -= (hours * 60);
hours -= (days * 24);
days -= (hours * 24);
}
return "Time elapsed: " + days + "days " + hours + "h " + minutes + "min " + seconds + "s";
}
private long calculateTimeDifference() {
long timeTaken = (long) ((endtime - starttime) * (1 * Math.pow(10, -9)));
return timeTaken;
}
public boolean excludeChars(String s) {
char[] arrayChars = s.toCharArray();
for (int i = 0; i < arrayChars.length; i++) {
characters.remove(arrayChars[i] + "");
}
if (characters.size() < maxLength) {
return false;
} else {
return true;
}
}
public int getMaxLength() {
return maxLength;
}
public int getMinLength() {
return minLength;
}
public void setIsDone(Boolean b) {
done = b;
}
public boolean isDone() {
return done;
}
}
HashBruter.java:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import javax.swing.JOptionPane;
public class HashBruter extends Bruter {
/*
* public static void main(String[] args) {
*
* final HashBruter hb = new HashBruter();
*
* hb.setMaxLength(5); hb.setMinLength(1);
*
* hb.addSpecialCharacters(); hb.addUpperCaseLetters();
* hb.addLowerCaseLetters(); hb.addDigits();
*
* hb.setType("sha-512");
*
* hb.setHash("282154720ABD4FA76AD7CD5F8806AA8A19AEFB6D10042B0D57A311B86087DE4DE3186A92019D6EE51035106EE088DC6007BEB7BE46994D1463999968FBE9760E");
*
* Thread thread = new Thread(new Runnable() {
*
* #Override public void run() { hb.tryBruteForce(); } });
*
* thread.start();
*
* while (!hb.isFound()) { System.out.println("Hash: " +
* hb.getGeneratedHash()); System.out.println("Number of Possibilities: " +
* hb.getNumberOfPossibilities()); System.out.println("Checked hashes: " +
* hb.getCounter()); System.out.println("Estimated hashes left: " +
* hb.getRemainder()); }
*
* System.out.println("Found " + hb.getType() + " hash collision: " +
* hb.getGeneratedHash() + " password is: " + hb.getPassword());
*
* }
*/
public String hash, generatedHash, password;
public String type;
public String getType() {
return type;
}
public String getPassword() {
return password;
}
public void setHash(String p) {
hash = p;
}
public void setType(String digestType) {
type = digestType;
}
public String getGeneratedHash() {
return generatedHash;
}
public void tryBruteForce() {
starttime = System.nanoTime();
for (int size = minLength; size <= maxLength; size++) {
if (found == true || done == true) {
break;
} else {
while (paused) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
generateAllPossibleCombinations("", size);
}
}
done = true;
}
private void generateAllPossibleCombinations(String baseString, int length) {
while (paused) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
if (found == false || done == false) {
if (baseString.length() == length) {
if(type.equalsIgnoreCase("crc32")) {
generatedHash = generateCRC32(baseString);
} else if(type.equalsIgnoreCase("adler32")) {
generatedHash = generateAdler32(baseString);
} else if(type.equalsIgnoreCase("crc16")) {
generatedHash=generateCRC16(baseString);
} else if(type.equalsIgnoreCase("crc64")) {
generatedHash=generateCRC64(baseString.getBytes());
}
else {
generatedHash = generateHash(baseString.toCharArray());
}
password = baseString;
if (hash.equals(generatedHash)) {
password = baseString;
found = true;
done = true;
}
count++;
} else if (baseString.length() < length) {
for (int n = 0; n < characters.size(); n++) {
generateAllPossibleCombinations(baseString + characters.get(n), length);
}
}
}
}
private String generateHash(char[] passwordChar) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance(type);
} catch (NoSuchAlgorithmException e1) {
JOptionPane.showMessageDialog(null, "No such algorithm for hashes exists", "Error", JOptionPane.ERROR_MESSAGE);
}
String passwordString = new String(passwordChar);
byte[] passwordByte = passwordString.getBytes();
md.update(passwordByte, 0, passwordByte.length);
byte[] encodedPassword = md.digest();
String encodedPasswordInString = toHexString(encodedPassword);
return encodedPasswordInString;
}
private void byte2hex(byte b, StringBuffer buf) {
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
private String toHexString(byte[] block) {
StringBuffer buf = new StringBuffer();
int len = block.length;
for (int i = 0; i < len; i++) {
byte2hex(block[i], buf);
}
return buf.toString();
}
private String generateCRC32(String baseString) {
//Convert string to bytes
byte bytes[] = baseString.getBytes();
Checksum checksum = new CRC32();
/*
* To compute the CRC32 checksum for byte array, use
*
* void update(bytes[] b, int start, int length)
* method of CRC32 class.
*/
checksum.update(bytes,0,bytes.length);
/*
* Get the generated checksum using
* getValue method of CRC32 class.
*/
return String.valueOf(checksum.getValue());
}
private String generateAdler32(String baseString) {
//Convert string to bytes
byte bytes[] = baseString.getBytes();
Checksum checksum = new Adler32();
/*
* To compute the CRC32 checksum for byte array, use
*
* void update(bytes[] b, int start, int length)
* method of CRC32 class.
*/
checksum.update(bytes,0,bytes.length);
/*
* Get the generated checksum using
* getValue method of CRC32 class.
*/
return String.valueOf(checksum.getValue());
}
/*************************************************************************
* Compilation: javac CRC16.java
* Execution: java CRC16 s
*
* Reads in a string s as a command-line argument, and prints out
* its 16-bit Cyclic Redundancy Check (CRC16). Uses a lookup table.
*
* Reference: http://www.gelato.unsw.edu.au/lxr/source/lib/crc16.c
*
* % java CRC16 123456789
* CRC16 = bb3d
*
* Uses irreducible polynomial: 1 + x^2 + x^15 + x^16
*
*
*************************************************************************/
private String generateCRC16(String baseString) {
int[] table = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
};
byte[] bytes = baseString.getBytes();
int crc = 0x0000;
for (byte b : bytes) {
crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
}
return Integer.toHexString(crc);
}
/*******************************************************************************
* Copyright (c) 2009, 2012 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc R. Hoffmann - initial API and implementation
*
*******************************************************************************/
/**
* CRC64 checksum calculator based on the polynom specified in ISO 3309. The
* implementation is based on the following publications:
*
* <ul>
* <li>http://en.wikipedia.org/wiki/Cyclic_redundancy_check</li>
* <li>http://www.geocities.com/SiliconValley/Pines/8659/crc.htm</li>
* </ul>
*/
private static final long POLY64REV = 0xd800000000000000L;
private static final long[] LOOKUPTABLE;
static {
LOOKUPTABLE = new long[0x100];
for (int i = 0; i < 0x100; i++) {
long v = i;
for (int j = 0; j < 8; j++) {
if ((v & 1) == 1) {
v = (v >>> 1) ^ POLY64REV;
} else {
v = (v >>> 1);
}
}
LOOKUPTABLE[i] = v;
}
}
/**
* Calculates the CRC64 checksum for the given data array.
*
* #param data
* data to calculate checksum for
* #return checksum value
*/
public static String generateCRC64(final byte[] data) {
long sum = 0;
for (int i = 0; i < data.length; i++) {
final int lookupidx = ((int) sum ^ data[i]) & 0xff;
sum = (sum >>> 8) ^ LOOKUPTABLE[lookupidx];
}
return String.valueOf(sum);
}
}
you would use it like:
final HashBruter hb = new HashBruter();
hb.setMaxLength(5); hb.setMinLength(1);
hb.addSpecialCharacters(); hb.addUpperCaseLetters();
hb.addLowerCaseLetters(); hb.addDigits();
hb.setType("sha-512");
hb.setHash("282154720ABD4FA76AD7CD5F8806AA8A19AEFB6D10042B0D57A311B86087DE4DE3186A92019D6EE51035106EE088DC6007BEB7BE46994D1463999968FBE9760E");
Thread thread = new Thread(new Runnable() {
#Override public void run() { hb.tryBruteForce(); } });
thread.start();
while (!hb.isFound()) { System.out.println("Hash: " +
hb.getGeneratedHash()); System.out.println("Number of Possibilities: " +
hb.getNumberOfPossibilities()); System.out.println("Checked hashes: " +
hb.getCounter()); System.out.println("Estimated hashes left: " +
hb.getRemainder()); }
System.out.println("Found " + hb.getType() + " hash collision: " +
hb.getGeneratedHash() + " password is: " + hb.getPassword());

Related

Having troubles with my binary search in java

When I run the below code I can not get it to give me a positive result. I can get this code to run, but once I add the binary search portion of the code, it keeps telling me my value is not in the list. And I know the value is on the list. Can someone please tell me what I did wrong? I want it to tell me the house value and the year of that value. Any help will be much appreciated.
import javax.swing.JOptionPane;
import java.util.*;
import java.util.Arrays;
static class House implements Comparable<House> {
private int price;
private int year;
public House(int price, int year) {
this.price = price;
this.year = year;
}
public int getPrice() {
return price;
}
public int getYear() {
return year;
}
#Override
public String toString() {
return "{" + "Price='" + price + '\'' +
", Year=" + year + '}';
}
#Override
public int compareTo(House o) {
if (this.year != o.getYear()) {
return this.year - o.getYear();
}
return this.price;
}
}
public static void main(String[] args)
{
BinarySearch ob = new BinarySearch();
House[] house = { new House(85480, 2013), new House(98873, 2012), new House(150592, 2022), new House(98035, 2014),
new House(114730, 2017), new House(178124, 2023), new House(137676, 2019),new House(104548, 2015),
new House(151330, 2021), new House(114730, 2016), new House(144452, 2020), new House(121614, 2018)};
System.out.println("Original Array of House objects:");
System.out.println(Arrays.toString(house));
Arrays.sort(house);
System.out.println("\nSorted Array of House objects:");
System.out.println(Arrays.toString(house));
String input = JOptionPane.showInputDialog("What house value do you want to search for: ");
int input2=Integer.parseInt(input);
int x = input2;
int result = ob.binarySearch(house, x);
if (result == -1)
{
JOptionPane.showMessageDialog(null, "The house value you are looking for is not in the list. ");
}
else
{
JOptionPane.showMessageDialog(null, "The house value is " + x + " year = " + "index " + result);
}
}
static class BinarySearch
{
int binarySearch(House[] house, int x)
{
int left = 0, right = house.length - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (house.length == x)
return mid;
if (house.length < x)
left = mid + 1;
else
right = mid - 1;
}
return -1;
}
}
}

Optimizing Replacing Bytes of Some File in Java 8

I have this method in Java and I want to improve it.
The method is used to replace some part (at the beginning, in the middle or at the end) of some File with the new bytes (the selected part can be replaced by less or more bytes).
The selection is done, by position(start) and quantity.
I can't to use external libraries (guava, or some other).
Here my old code:
public static void replaceBytesFile(RandomAccessFile rafTarget,
byte[] replacers, int start, int quantity) {
//replaces exact amount of bytes of a file starting at a specified position
RandomAccessFile rafTemp = null;
//Ini Select a Random NonExistent File
File userDirectory = new File(System.getProperty("user.dir"));
File temporalFile;
boolean existsTemporalFile = false;
String temporalFilename = "";
while (!existsTemporalFile) {
temporalFilename = "File_" + Double.toString(100000 * Math.random()) + ".tmp";
temporalFilename = userDirectory + MethodGen.FS + temporalFilename;
temporalFile = new File(temporalFilename);
if (!temporalFile.exists()) {
existsTemporalFile = true;
}
}
//End Select a Random NonExistent File
try {
rafTemp = new RandomAccessFile(temporalFilename, "rw");
int workBufferSize = 65536;
//Ini Copy first (Start - 1) MethodBytes
int step = workBufferSize;
int countPosition = 0;
while (countPosition < start) {
rafTarget.seek(countPosition);
rafTemp.seek(countPosition);
if ((start - countPosition) < step) {
step = start - countPosition;
}
byte[] WorkBuffer = new byte[step];
rafTarget.read(WorkBuffer);
rafTemp.write(WorkBuffer);
countPosition += step;
}
//End Copy first (start - 1) MethodBytes
rafTemp.write(replacers);
rafTarget.seek(start + quantity);
int end = (int) rafTarget.length();
//Ini Copy last MethodBytes
step = workBufferSize;
countPosition = start + quantity;
while (countPosition < end) {
rafTarget.seek(countPosition);
rafTemp.seek(countPosition - quantity + replacers.length);
if ((end - countPosition) <= step) {
step = end - countPosition;
}
byte[] WorkBuffer = new byte[step];
rafTarget.read(WorkBuffer);
rafTemp.write(WorkBuffer);
countPosition += step;
}
//End Copy last MethodBytes
rafTarget.setLength(0);
step = workBufferSize;
countPosition = 0;
end = (int) rafTemp.length();
//Ini Copy all MethodBytes to original
while (countPosition < end) {
rafTemp.seek(countPosition);
rafTarget.seek(countPosition);
if ((end - countPosition) <= step) {
step = end - countPosition;
}
byte[] WorkBuffer = new byte[step];
rafTemp.read(WorkBuffer);
rafTarget.write(WorkBuffer);
countPosition += step;
}
//End Copy all MethodBytes to original
rafTemp.close();
temporalFile = new File(temporalFilename);
temporalFile.delete();
} catch (IOException ioe) {
System.out.println(ioe.toString());
} finally {
try {
if (rafTemp != null) {
rafTemp.close();
}
} catch (IOException e) {
}
}
}
I'm copying manually in from original file to temporal file where the changes are performed, later ,
My code is working, but I want to know some best alternative in Java 8 (preferred).
Now How is test?
public static void main(String[] args) {
String originalFilename = "OriginalTraveling.txt";
String copiedFilename = "TravelingToBeChanged.txt";
Path copiedPath = Paths.get(copiedFilename);
Path originalPath = new File(originalFilename).toPath();
System.out.println("filename:" + originalFilename);
String contet = "I want to travel to my Country.";
try {
RandomAccessFile raf = new RandomAccessFile(originalFilename, "rw");
putBytesFile(raf, contet.getBytes(), 0);
Files.copy(originalPath, copiedPath, StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e) {
System.out.println("Exception caught " + e.toString());
}
try {
RandomAccessFile raf = new RandomAccessFile(copiedFilename, "rw");
String toBeChanged = "my Country.";
String toBeInserted = "India, China, Europe, Latin America, Australia.";
int position = contet.indexOf(toBeChanged);
replaceBytesFile(raf, toBeInserted.getBytes(), position, toBeChanged.length());
}
catch (IOException e) {
System.out.println("Exception caught " + e.toString());
}
try {
RandomAccessFile raf = new RandomAccessFile(copiedFilename, "rw");
String replacedContent = new String(getBytesFile(raf, 0, (int) raf.length()));
String toBeChanged = "Latin America";
String toBeInserted = "Colombia";
int position = replacedContent.indexOf(toBeChanged);
replaceBytesFile(raf, toBeInserted.getBytes(), position, toBeChanged.length());
} catch (IOException e) {
System.out.println("Exception caught " + e.toString());
}
}
Method to put Bytes!
public static void putBytesFile(RandomAccessFile RAFTarget, byte[] content, int position) {
int size = content.length;
try {
long oldPosition = RAFTarget.getFilePointer();
if (!((position < 0) || !(size > 0))) {
RAFTarget.seek(position);
RAFTarget.write(content);
RAFTarget.seek(oldPosition);
}
} catch (java.io.IOException e) {
System.out.println(e.toString());
}
}
Method Get Files!
public static byte[] getBytesFile(RandomAccessFile RAFSource, int position, int quantity) {
byte[] content = null;
try {
long oldPosition = RAFSource.getFilePointer();
if ((position < 0) || !(quantity > 0)) {
return (content);
} else {
if (RAFSource.length() < (position + quantity)) {
quantity = (int) RAFSource.length() - position;
}
RAFSource.seek(position);
content = new byte[quantity];
RAFSource.read(content);
RAFSource.seek(oldPosition);
}
} catch (java.io.IOException e) {
System.out.println(e.toString());
}
return content;
}
Content of OriginalTraveling.txt
I want to travel to my Country.
Content of TravelingToBeChanged.txt
I want to travel to India, China, Europe, Latin America, Australia.
Finally the Content of TravelingToBeChanged.txt
I want to travel to India, China, Europe, Colombia, Australia.
If it can be noticed, they are NOT changed by the same number of bytes.
Do you know some alternative to replace contents of File?
Even for ancient code, this looks unnecessary complicated.
E.g. instead of
//Ini Select a Random NonExistent File
File userDirectory = new File(System.getProperty("user.dir"));
File temporalFile;
boolean existsTemporalFile = false;
String temporalFilename = "";
while (!existsTemporalFile) {
temporalFilename = "File_" + Double.toString(100000 * Math.random()) + ".tmp";
temporalFilename = userDirectory + MethodGen.FS + temporalFilename;
temporalFile = new File(temporalFilename);
if (!temporalFile.exists()) {
existsTemporalFile = true;
}
}
just use
File temporalFile = File.createTempFile("File_", ".tmp", userDirectory);
See createTempFile
Further, instead of
int step = workBufferSize;
int countPosition = 0;
while (countPosition < start) {
rafTarget.seek(countPosition);
rafTemp.seek(countPosition);
if ((start - countPosition) < step) {
step = start - countPosition;
}
byte[] WorkBuffer = new byte[step];
rafTarget.read(WorkBuffer);
rafTemp.write(WorkBuffer);
countPosition += step;
}
Use
for(int step=workBufferSize, countPosition=0; countPosition < start; countPosition += step){
rafTarget.seek(countPosition);
rafTemp.seek(countPosition);
if ((start - countPosition) < step) {
step = start - countPosition;
}
byte[] WorkBuffer = new byte[step];
rafTarget.read(WorkBuffer);
rafTemp.write(WorkBuffer);
}
As you clearly have an initial statement, a condition and an increment operation, in other words, a typical for loop. The same applies to the other two while loops.
However, with newer APIs, things are much simpler anyway:
// consider using long for position and Path for the file, unless
// the RandomAccessFile is really needed for other purposes
public static void replaceBytesFile(RandomAccessFile rafTarget,
byte[] replacers, int start, int quantity) throws IOException {
// no need to force a particular directory for the temp file
Path tmp = Files.createTempFile("File_", ".tmp");
// use import static java.nio.file.StandardOpenOption.*;
// try( ... ) closes automatically, perfect for a temp file with DELETE_ON_CLOSE
try(FileChannel tmpCh = FileChannel.open(tmp, READ, WRITE, DELETE_ON_CLOSE)) {
// closing the target channel would also close rafTarget RandomAccessFile
FileChannel target = rafTarget.getChannel();
// just keep the data before start position, only copy remainder
long retainStart = start + (long)quantity, toCopy = target.size() - retainStart;
target.transferTo(retainStart, toCopy, tmpCh);
// write the replacement
target.write(ByteBuffer.wrap(replacers), start);
// copy back the remainder, to the new position
tmpCh.position(0);
target.transferFrom(tmpCh, start + (long)replacers.length, toCopy);
// adapt the length if necessary
target.truncate(start + toCopy + replacers.length);
}
}

JFreeChart LogAxis Frequency/Resistance multipliers

I'm trying to figure out how to dynamically format the values on the axes of my line chart based on the multiplier.
I'm using LogAxis for both the X and Y axes, as follows:
final LogAxis rangeAxis = new LogAxis(valueAxisLabel);
rangeAxis.setStandardTickUnits(LogAxis.createLogTickUnits(Locale.ENGLISH));
rangeAxis.setRange(0.01, 10.0); //10 mOhms to 10 Ohms
plot.setRangeAxis(rangeAxis);
final LogAxis domainAxis = new LogAxis(frequencyAxisLabel);
domainAxis.setStandardTickUnits(LogAxis.createLogTickUnits(Locale.ENGLISH));
domainAxis.setRange(100, 10000000); //100Hz to 10MHz
plot.setDomainAxis(domainAxis);
I currently have the following values on my Y axis:
0.01, 0.1, 1, 10
But would like it to display as
10mOhm, 100mOhm, 1Ohm, 10Ohm
and on the X axis I have
100, 1,000, 10,000, 100,000, 1,000,000, 10,000,000
but would like to see
100Hz, 1kHz, 10kHz, 100kHz, 1MHz, 10MHz
I know you can override the NumberFormat used on the axis, but I haven't found a way to do so to where the NumberFormat is overridden dynamically based on the value like this. Is this possible? Do I need to extend NumberFormat to do this?
EDIT:
Per the accepted answer, I extended NumberFormat as follows (Note that the implementation isn't complete but rather hacked for quick demo purposes for my boss)
public class UnitNumberFormat extends NumberFormat
{
/**
*
*/
private static final long serialVersionUID = -8544764432101798895L;
private UnitValue unitValue;
public UnitNumberFormat(UnitValue unitValue)
{
super();
this.unitValue = unitValue;
}
/*
* (non-Javadoc)
* #see java.text.NumberFormat#format(double, java.lang.StringBuffer,
* java.text.FieldPosition)
*/
#Override
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos)
{
StringBuffer formattedValue = new StringBuffer();
BigDecimal bd = new BigDecimal(number);
BigDecimal multiplier = new BigDecimal(1);
String multiplierString = "";
if(number < 1 && number > 0)
{
multiplier = new BigDecimal(1000);
multiplierString = "m";
}
else if(number < 1000 && number >= 1)
{
multiplier = new BigDecimal(1);
multiplierString = "";
}
else if(number < 1000000 && number >= 1000)
{
multiplier = new BigDecimal(1. / 1000);
multiplierString = "k";
}
else if(number < 1000000000 && number >= 1000000)
{
multiplier = new BigDecimal(1. / 1000000);
multiplierString = "M";
}
else
{
throw new NumberFormatException("This formatter doesn't yet support values beyond Mega");
}
bd = bd.multiply(multiplier).round(new MathContext(1, RoundingMode.HALF_UP));
formattedValue.append(bd.toPlainString());
formattedValue.append(" ");
formattedValue.append(multiplierString);
formattedValue.append(this.unitValue.getUnit());
return formattedValue;
}
/*
* (non-Javadoc)
* #see java.text.NumberFormat#format(long, java.lang.StringBuffer,
* java.text.FieldPosition)
*/
#Override
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos)
{
return null;
}
/*
* (non-Javadoc)
* #see java.text.NumberFormat#parse(java.lang.String,
* java.text.ParsePosition)
*/
#Override
public Number parse(String source, ParsePosition parsePosition)
{
return null;
}
}
and UnitValue is as follows:
public enum UnitValue {
HERTZ("Hz"),
OHMS("Ω"),
;
private final String unit;
private UnitValue(String unit)
{
this.unit = unit;
}
/**
* #return the unit
*/
public String getUnit()
{
return unit;
}
}
Yes you do need to subclass NumberFormat there is an example here

SQL Server : Convert binary(16) to character string [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to decrypt md5 hashes?
Is it possible to get a string from MD5 in Java?
Firstly a string is converted to MD5 checksum, is it possible to get this MD5 checksum back to the original text?
I'm assuming you use MessageDigest, any help is greatly appreciated, even other java libraries.
Just want to also point out on if it not possible how this app is able to it: https://play.google.com/store/apps/details?id=com.fab.md5&hl=en
I even converted some text to MD5 checksum using another application and used this checksum to see if the app was able to convert it back to text and it did.
No, that's not really possible, as
there can be more than one string giving the same MD5
it was designed to be hard to "reverse"
The goal of the MD5 and its family of hashing functions is
to get short "extracts" from long string
to make it hard to guess where they come from
to make it hard to find collisions, that is other words having the same hash (which is a very similar exigence as the second one)
Think that you can get the MD5 of any string, even very long. And the MD5 is only 16 bytes long (32 if you write it in hexa to store or distribute it more easily). If you could reverse them, you'd have a magical compacting scheme.
This being said, as there aren't so many short strings (passwords...) used in the world, you can test them from a dictionary (that's called "brute force attack") or even google for your MD5. If the word is common and wasn't salted, you have a reasonable chance to succeed...
Its not possible thats the whole point of hashing. You can however bruteforce by going through all possibilities (using all possible digits characters in every possible order) and hashing them and checking for a collision.
for more information on hashing and MD5 etc see: http://en.wikipedia.org/wiki/MD5 , http://en.wikipedia.org/wiki/Hash_function , http://en.wikipedia.org/wiki/Cryptographic_hash_function and http://onin.com/hhh/hhhexpl.html
I myself created my own app to do this, its open source you can check the link: http://sourceforge.net/projects/jpassrecovery/ and of course the source. Here is the source for easy access it has a basic implementation in the comments:
Bruter.java:
import java.util.ArrayList;
public class Bruter {
public ArrayList<String> characters = new ArrayList<>();
public boolean found = false;
public int maxLength;
public int minLength;
public int count;
long starttime, endtime;
public int minutes, seconds, hours, days;
public char[] specialCharacters = {'~', '`', '!', '#', '#', '$', '%', '^',
'&', '*', '(', ')', '_', '-', '+', '=', '{', '}', '[', ']', '|', '\\',
';', ':', '\'', '"', '<', '.', ',', '>', '/', '?', ' '};
public boolean done = false;
public boolean paused = false;
public boolean isFound() {
return found;
}
public void setPaused(boolean paused) {
this.paused = paused;
}
public boolean isPaused() {
return paused;
}
public void setFound(boolean found) {
this.found = found;
}
public synchronized void setEndtime(long endtime) {
this.endtime = endtime;
}
public int getCounter() {
return count;
}
public long getRemainder() {
return getNumberOfPossibilities() - count;
}
public long getNumberOfPossibilities() {
long possibilities = 0;
for (int i = minLength; i <= maxLength; i++) {
possibilities += (long) Math.pow(characters.size(), i);
}
return possibilities;
}
public void addExtendedSet() {
for (char c = (char) 0; c <= (char) 31; c++) {
characters.add(String.valueOf(c));
}
}
public void addStandardCharacterSet() {
for (char c = (char) 32; c <= (char) 127; c++) {
characters.add(String.valueOf(c));
}
}
public void addLowerCaseLetters() {
for (char c = 'a'; c <= 'z'; c++) {
characters.add(String.valueOf(c));
}
}
public void addDigits() {
for (int c = 0; c <= 9; c++) {
characters.add(String.valueOf(c));
}
}
public void addUpperCaseLetters() {
for (char c = 'A'; c <= 'Z'; c++) {
characters.add(String.valueOf(c));
}
}
public void addSpecialCharacters() {
for (char c : specialCharacters) {
characters.add(String.valueOf(c));
}
}
public void setMaxLength(int i) {
maxLength = i;
}
public void setMinLength(int i) {
minLength = i;
}
public int getPerSecond() {
int i;
try {
i = (int) (getCounter() / calculateTimeDifference());
} catch (Exception ex) {
return 0;
}
return i;
}
public String calculateTimeElapsed() {
long timeTaken = calculateTimeDifference();
seconds = (int) timeTaken;
if (seconds > 60) {
minutes = (int) (seconds / 60);
if (minutes * 60 > seconds) {
minutes = minutes - 1;
}
if (minutes > 60) {
hours = (int) minutes / 60;
if (hours * 60 > minutes) {
hours = hours - 1;
}
}
if (hours > 24) {
days = (int) hours / 24;
if (days * 24 > hours) {
days = days - 1;
}
}
seconds -= (minutes * 60);
minutes -= (hours * 60);
hours -= (days * 24);
days -= (hours * 24);
}
return "Time elapsed: " + days + "days " + hours + "h " + minutes + "min " + seconds + "s";
}
private long calculateTimeDifference() {
long timeTaken = (long) ((endtime - starttime) * (1 * Math.pow(10, -9)));
return timeTaken;
}
public boolean excludeChars(String s) {
char[] arrayChars = s.toCharArray();
for (int i = 0; i < arrayChars.length; i++) {
characters.remove(arrayChars[i] + "");
}
if (characters.size() < maxLength) {
return false;
} else {
return true;
}
}
public int getMaxLength() {
return maxLength;
}
public int getMinLength() {
return minLength;
}
public void setIsDone(Boolean b) {
done = b;
}
public boolean isDone() {
return done;
}
}
HashBruter.java:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.Adler32;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import javax.swing.JOptionPane;
public class HashBruter extends Bruter {
/*
* public static void main(String[] args) {
*
* final HashBruter hb = new HashBruter();
*
* hb.setMaxLength(5); hb.setMinLength(1);
*
* hb.addSpecialCharacters(); hb.addUpperCaseLetters();
* hb.addLowerCaseLetters(); hb.addDigits();
*
* hb.setType("sha-512");
*
* hb.setHash("282154720ABD4FA76AD7CD5F8806AA8A19AEFB6D10042B0D57A311B86087DE4DE3186A92019D6EE51035106EE088DC6007BEB7BE46994D1463999968FBE9760E");
*
* Thread thread = new Thread(new Runnable() {
*
* #Override public void run() { hb.tryBruteForce(); } });
*
* thread.start();
*
* while (!hb.isFound()) { System.out.println("Hash: " +
* hb.getGeneratedHash()); System.out.println("Number of Possibilities: " +
* hb.getNumberOfPossibilities()); System.out.println("Checked hashes: " +
* hb.getCounter()); System.out.println("Estimated hashes left: " +
* hb.getRemainder()); }
*
* System.out.println("Found " + hb.getType() + " hash collision: " +
* hb.getGeneratedHash() + " password is: " + hb.getPassword());
*
* }
*/
public String hash, generatedHash, password;
public String type;
public String getType() {
return type;
}
public String getPassword() {
return password;
}
public void setHash(String p) {
hash = p;
}
public void setType(String digestType) {
type = digestType;
}
public String getGeneratedHash() {
return generatedHash;
}
public void tryBruteForce() {
starttime = System.nanoTime();
for (int size = minLength; size <= maxLength; size++) {
if (found == true || done == true) {
break;
} else {
while (paused) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
generateAllPossibleCombinations("", size);
}
}
done = true;
}
private void generateAllPossibleCombinations(String baseString, int length) {
while (paused) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
if (found == false || done == false) {
if (baseString.length() == length) {
if(type.equalsIgnoreCase("crc32")) {
generatedHash = generateCRC32(baseString);
} else if(type.equalsIgnoreCase("adler32")) {
generatedHash = generateAdler32(baseString);
} else if(type.equalsIgnoreCase("crc16")) {
generatedHash=generateCRC16(baseString);
} else if(type.equalsIgnoreCase("crc64")) {
generatedHash=generateCRC64(baseString.getBytes());
}
else {
generatedHash = generateHash(baseString.toCharArray());
}
password = baseString;
if (hash.equals(generatedHash)) {
password = baseString;
found = true;
done = true;
}
count++;
} else if (baseString.length() < length) {
for (int n = 0; n < characters.size(); n++) {
generateAllPossibleCombinations(baseString + characters.get(n), length);
}
}
}
}
private String generateHash(char[] passwordChar) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance(type);
} catch (NoSuchAlgorithmException e1) {
JOptionPane.showMessageDialog(null, "No such algorithm for hashes exists", "Error", JOptionPane.ERROR_MESSAGE);
}
String passwordString = new String(passwordChar);
byte[] passwordByte = passwordString.getBytes();
md.update(passwordByte, 0, passwordByte.length);
byte[] encodedPassword = md.digest();
String encodedPasswordInString = toHexString(encodedPassword);
return encodedPasswordInString;
}
private void byte2hex(byte b, StringBuffer buf) {
char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
private String toHexString(byte[] block) {
StringBuffer buf = new StringBuffer();
int len = block.length;
for (int i = 0; i < len; i++) {
byte2hex(block[i], buf);
}
return buf.toString();
}
private String generateCRC32(String baseString) {
//Convert string to bytes
byte bytes[] = baseString.getBytes();
Checksum checksum = new CRC32();
/*
* To compute the CRC32 checksum for byte array, use
*
* void update(bytes[] b, int start, int length)
* method of CRC32 class.
*/
checksum.update(bytes,0,bytes.length);
/*
* Get the generated checksum using
* getValue method of CRC32 class.
*/
return String.valueOf(checksum.getValue());
}
private String generateAdler32(String baseString) {
//Convert string to bytes
byte bytes[] = baseString.getBytes();
Checksum checksum = new Adler32();
/*
* To compute the CRC32 checksum for byte array, use
*
* void update(bytes[] b, int start, int length)
* method of CRC32 class.
*/
checksum.update(bytes,0,bytes.length);
/*
* Get the generated checksum using
* getValue method of CRC32 class.
*/
return String.valueOf(checksum.getValue());
}
/*************************************************************************
* Compilation: javac CRC16.java
* Execution: java CRC16 s
*
* Reads in a string s as a command-line argument, and prints out
* its 16-bit Cyclic Redundancy Check (CRC16). Uses a lookup table.
*
* Reference: http://www.gelato.unsw.edu.au/lxr/source/lib/crc16.c
*
* % java CRC16 123456789
* CRC16 = bb3d
*
* Uses irreducible polynomial: 1 + x^2 + x^15 + x^16
*
*
*************************************************************************/
private String generateCRC16(String baseString) {
int[] table = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
};
byte[] bytes = baseString.getBytes();
int crc = 0x0000;
for (byte b : bytes) {
crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
}
return Integer.toHexString(crc);
}
/*******************************************************************************
* Copyright (c) 2009, 2012 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc R. Hoffmann - initial API and implementation
*
*******************************************************************************/
/**
* CRC64 checksum calculator based on the polynom specified in ISO 3309. The
* implementation is based on the following publications:
*
* <ul>
* <li>http://en.wikipedia.org/wiki/Cyclic_redundancy_check</li>
* <li>http://www.geocities.com/SiliconValley/Pines/8659/crc.htm</li>
* </ul>
*/
private static final long POLY64REV = 0xd800000000000000L;
private static final long[] LOOKUPTABLE;
static {
LOOKUPTABLE = new long[0x100];
for (int i = 0; i < 0x100; i++) {
long v = i;
for (int j = 0; j < 8; j++) {
if ((v & 1) == 1) {
v = (v >>> 1) ^ POLY64REV;
} else {
v = (v >>> 1);
}
}
LOOKUPTABLE[i] = v;
}
}
/**
* Calculates the CRC64 checksum for the given data array.
*
* #param data
* data to calculate checksum for
* #return checksum value
*/
public static String generateCRC64(final byte[] data) {
long sum = 0;
for (int i = 0; i < data.length; i++) {
final int lookupidx = ((int) sum ^ data[i]) & 0xff;
sum = (sum >>> 8) ^ LOOKUPTABLE[lookupidx];
}
return String.valueOf(sum);
}
}
you would use it like:
final HashBruter hb = new HashBruter();
hb.setMaxLength(5); hb.setMinLength(1);
hb.addSpecialCharacters(); hb.addUpperCaseLetters();
hb.addLowerCaseLetters(); hb.addDigits();
hb.setType("sha-512");
hb.setHash("282154720ABD4FA76AD7CD5F8806AA8A19AEFB6D10042B0D57A311B86087DE4DE3186A92019D6EE51035106EE088DC6007BEB7BE46994D1463999968FBE9760E");
Thread thread = new Thread(new Runnable() {
#Override public void run() { hb.tryBruteForce(); } });
thread.start();
while (!hb.isFound()) { System.out.println("Hash: " +
hb.getGeneratedHash()); System.out.println("Number of Possibilities: " +
hb.getNumberOfPossibilities()); System.out.println("Checked hashes: " +
hb.getCounter()); System.out.println("Estimated hashes left: " +
hb.getRemainder()); }
System.out.println("Found " + hb.getType() + " hash collision: " +
hb.getGeneratedHash() + " password is: " + hb.getPassword());

Sorting array of Strings in lexicographic order

I am trying to modify the merge sort algorithm to sort an array of strings in lexicographic order, I am not really advanced so I may be making some newbie mistakes. This is the main and the tester and the mergesorter.
public class MergeSorter
{
private int[] a;
private int[] left_side;
private int[] right_side;
public MergeSorter(int[] anArray)
{
a = anArray;
}
public void sort()
{
int size = 1;
int from = 0;
int to = a.length - 1;
while (size < to - from)
{
int offset = 0;
while(offset < to)
{
merge(from, to, offset);
offset = offset + (2 * size);
}
}
size = 2 * size;
}
public void merge(int from, int mid, int to)
{
System.out.println("Merging " + from + "..." + mid
+ " and " + (mid + 1) + "..." + to);
}
}
And ...
import java.util.Arrays;
public class MergeSortDemo
{
public static void main(String[] args)
{
String[] array = new String[]{"Jenny","Rob","Dereck","Mike","Dan"};
System.out.println(Arrays.toString(array));
MergeSorter sorter = new MergeSorter(array);
sorter.sort();
System.out.println(Arrays.toString(array));
}
}

Resources