Sorting array of Strings in lexicographic order - arrays

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));
}
}

Related

Calling array method in main class

How can i call runningSum method in main with new array of intigers so it return result?
class Main {
public static void main(String[] args) {
}
public int[] runningSum(int[] nums) {
int[] result = new int[nums.length];
result[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
result[i] = result[i - 1] + nums[i];
}
return result;
}
}
I have no idea how to call it.
Add static modifier to your runningSum method. example
public static void main(String[] args) {
int[] myNum = {10, 20, 30, 40};
int[] result = runningSum(myNum);
for (int item : result){
System.out.println(item);
}
}
public static int[] runningSum(int[] nums) {
int[] result = new int[nums.length];
result[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
result[i] = result[i - 1] + nums[i];
}
return result;
}

Array challenge

public class Testfor
{
public static int ArrayChallenge(int[] arr)
{
int[] temp = new int[arr.length - 1];
int diff = 0;
for (int i = 0; i < arr.length - 1; i++)
{
diff = Math.abs(arr[i] - arr[i + 1]);
temp[i] = diff;
}
arr = temp;
for (int i:arr)
{
System.out.println(i);
}
if (arr.length > 1)
{
ArrayChallenge(arr);
}
else
{
diff = arr[0];
System.out.println("diff" + diff);
}
return diff;
}
public static void main(String[] args)
{
// keep this function call here
//Scanner s = new Scanner(System.in);
System.out.println("answer:" + ArrayChallenge(new int[] { 5, 7, 16, 1, 2 }));
}
}
Here the input is an array of integers finally the array should be reduced to the size of one element by finding the absolute difference between two elements.
I am using recursion to solve this but I am getting 1 as the answer can someone please someone help to solve it?
input:[5,7,16,1,2]
[2,9,15,1]
[7,6,14]
[1,8]
[7]--->the array should reduce in the following manner to get an answer and finally should return the last element
output:7
Just preserve the return value
public class Testfor
{
public static int ArrayChallenge(int[] arr)
{
int[] temp = new int[arr.length - 1];
int diff = 0;
for (int i = 0; i < arr.length - 1; i++)
{
diff = Math.abs(arr[i] - arr[i + 1]);
temp[i] = diff;
}
arr = temp;
for (int i:arr)
{
System.out.println(i);
}
if (arr.length > 1)
{
diff = ArrayChallenge(arr);
}
else
{
diff = arr[0];
System.out.println("diff" + diff);
}
return diff;
}
public static void main(String[] args)
{
// keep this function call here
//Scanner s = new Scanner(System.in);
System.out.println("answer:" + ArrayChallenge(new int[] { 5, 7, 16, 1, 2 }));
}
}

How can I store the results of permutation in a 2D array?

I need help writing this code to get the permutation of numbers.
I need to store all the permutations in a 2D array.
After output of the permutation, I then need to process 30 percent of the permutations in one method an the the rest in another method.
My code:
public class Permutation {
* #param args the command line arguments
*/
void printArray(int []a) {
for (int i = 0; i< a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println("");
}
void permute(int []a,int k ) {
if(k==a.length)
printArray(a);
else
for (int i = k; i< a.length; i++) {
int temp=a[k];
a[k]=a[i];
a[i]=temp;
permute(a,k+1);
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
public static void main(String[] args) {
Permutation p=new Permutation();
int a[]={1,2,3,4,5,6};
p.permute(a, 2);
}
}
This is my solution instead of a 2d array use an ArrayList
import java.util.ArrayList;
import java.util.Arrays;
/**
*
* #author David
*/
public class Permutations {
public static int[] a;
public final int SIZE = 6;
public final int NUMPERM;
public final ArrayList<int[]> newlist;
public Permutations()
{
a = new int[SIZE];
for(int x = 0; x < SIZE; x++)
a[x] = x+1;
NUMPERM = Factorial(a.length);
newlist = new ArrayList<>(NUMPERM);
}
public void permute()
{
permutation(a,0,a.length);
}
private void permutation(int array[],int start, int end)
{
newlist.add(saveArray(array));
if (start<end)
{
int i,j;
for(i=end-2; i>=start; i--)
{
for(j=i+1; j<end; j++)
{
Swap(array,i,j);
permutation(array,i+1,end);
}
Rotate_Left(array,i,end);
}
}
}
private int[] saveArray(int[] array)
{
int[] newarray = new int[array.length];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
public void Print()
{ //just to prove the list works
System.out.println("the current size of newlist is : " + newlist.size());
int[] array = new int[a.length];
for(int x = 0; x < newlist.size(); x++)
{
array = newlist.get(x);
System.out.println(Arrays.toString(array));
}
}
private void Swap(int array[],int i,int j)
{
int t;
t = array[i];
array[i] = array[j];
array[j] = t;
}
private void Rotate_Left(int array[],int start,int end)
{
int tmp = array[start];
for (int i=start; i < end-1; i++)
{
array[i] = array[i+1];
}
array[end-1] = tmp;
}
private int Factorial(int a)
{
int fact = 1;
for(int x = a; x > 0; x++)
fact *= a;
return fact;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Permutations newperm = new Permutations();
newperm.permute();
newperm.Print();
}
}
then all you have to do is send the list to the other functions and only use what you need from it.

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());

How to reverse MD5 to get the original 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());

Resources