-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit: basic Java template, password cracker
- Loading branch information
0 parents
commit 4646dd4
Showing
9 changed files
with
331 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff: | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/dictionaries | ||
|
||
# Sensitive or high-churn files: | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.xml | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
|
||
# Gradle: | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# CMake | ||
cmake-build-debug/ | ||
|
||
# Mongo Explorer plugin: | ||
.idea/**/mongoSettings.xml | ||
|
||
## File-based project format: | ||
*.iws | ||
|
||
## Plugin-specific files: | ||
|
||
# IntelliJ | ||
/out/ | ||
*.iml | ||
.settings/ | ||
.classpath | ||
.project | ||
*.swp | ||
.idea/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties |
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package AI; | ||
|
||
/** | ||
* Created by Nicola on 6/16/2017. | ||
*/ | ||
public class DNA { | ||
String genes; | ||
|
||
public DNA(String _genes) { | ||
this.genes = _genes; | ||
} | ||
|
||
public String getGenes() { | ||
return this.genes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package AI; | ||
|
||
import util.RandomUtil; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
|
||
/** | ||
* Created by Nicola on 6/16/2017. | ||
*/ | ||
public class Population { | ||
private ArrayList<DNA> population = new ArrayList(); | ||
private double mutationRate; | ||
private int maxPopulation; | ||
private String target; | ||
|
||
// Population class constructor | ||
public Population(double mutationRate, int maxPopulation, String target) { | ||
this.mutationRate = mutationRate; | ||
this.maxPopulation = maxPopulation; | ||
this.target = target; | ||
} | ||
|
||
//Initialize random population | ||
public void initPopulation() { | ||
for (int i = 0; i < maxPopulation; i++) | ||
this.getPopulation().add(new DNA(RandomUtil.randomString(target.length()))); | ||
} | ||
|
||
//Perform natural selection on the population: members | ||
//with higher fitness score have higher probability of | ||
//being select for reproduction | ||
public String naturalSelection() { | ||
HashMap<DNA, Integer> fitnessScores = calcPopulationFitness(this.target); | ||
if (fitnessScores.size() == 1) return (String) fitnessScores.keySet().toArray()[0]; | ||
ArrayList<DNA> matingPool = matingPool(fitnessScores); | ||
ArrayList<DNA> newGeneration = new ArrayList<>(); | ||
|
||
//Selection and reproduction | ||
for (int i = 0; i < maxPopulation; i++) { | ||
newGeneration.add(reproduce( | ||
matingPool.get(RandomUtil.min_maxBoundedInt(0, matingPool.size() - 1)), | ||
matingPool.get(RandomUtil.min_maxBoundedInt(0, matingPool.size() - 1)))); | ||
} | ||
|
||
//Replace population | ||
this.population.clear(); | ||
this.setPopulation(newGeneration); | ||
return null; | ||
} | ||
|
||
// Calculate fitness for each member in the given population | ||
public HashMap<DNA, Integer> calcPopulationFitness(String target) { | ||
HashMap<DNA, Integer> fitnessValues = new HashMap<>(); | ||
int maxFitnessScore = 0; | ||
DNA maxDNAfitnessScore = null; | ||
|
||
for (int i = 0; i < maxPopulation; i++) { | ||
DNA indexDNA = this.getPopulation().get(i); | ||
int indexFitness = calcIndividualFitness(indexDNA, target); | ||
|
||
if (indexFitness > maxFitnessScore) { | ||
maxFitnessScore = indexFitness; | ||
maxDNAfitnessScore = indexDNA; | ||
} | ||
|
||
//If optimal solution is found then return a single element -> this situation will be treated | ||
//in the calling method | ||
if (maxFitnessScore == target.length()) { | ||
fitnessValues.clear(); | ||
fitnessValues.put(indexDNA, indexFitness); | ||
break; | ||
} | ||
fitnessValues.put(indexDNA, indexFitness); | ||
} | ||
|
||
//DEBUG | ||
System.out.println("max fitness: " + maxDNAfitnessScore.getGenes() + " score: " + maxFitnessScore); | ||
return fitnessValues; | ||
} | ||
|
||
// Evaluate every single fitness score for each member in the population | ||
// In this case fitness score is incremented if the n-th gene (in this case the n-th letter) | ||
// corresponds to the n-th character of the target string | ||
public int calcIndividualFitness(DNA dna, String target) { | ||
int fitnessScore = 0; | ||
String genes = dna.getGenes(); | ||
|
||
for (int i = 0; i < target.length(); i++) | ||
if (genes.charAt(i) == target.charAt(i)) | ||
fitnessScore++; | ||
|
||
return fitnessScore; | ||
} | ||
|
||
//Create a mating pool selecting a couple of DNAs from the population, | ||
// evaluating each of them with their fitness score | ||
public ArrayList<DNA> matingPool(HashMap<DNA, Integer> fitnessScores) { | ||
ArrayList<DNA> poll = new ArrayList<>(); | ||
|
||
for (DNA indexDNA : fitnessScores.keySet()) | ||
for (int i = 0; i < fitnessScores.get(indexDNA); i++) | ||
poll.add(indexDNA); | ||
|
||
return poll; | ||
} | ||
|
||
//Create a new DNA given the 2 parents' DNAs | ||
//taking 50% genetic information from each one + consider | ||
//mutation rate | ||
public DNA reproduce(DNA p1, DNA p2) { | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append(p1.getGenes().substring(0, p1.getGenes().length() / 2)); | ||
sb.append(p2.getGenes().substring(p2.getGenes().length() / 2, p2.getGenes().length())); | ||
|
||
//perform mutation | ||
char[] child = new char[sb.length()]; | ||
sb.getChars(0, sb.length(), child, 0); | ||
|
||
for (int i = 0; i < sb.length(); i++) | ||
if (RandomUtil.extractWithRate(this.getMutationRate())) | ||
child[i] = RandomUtil.randomChar(); | ||
|
||
return new DNA(new String(child)); | ||
} | ||
|
||
//Getters and setters | ||
public double getMutationRate() { | ||
return mutationRate; | ||
} | ||
|
||
public void setMutationRate(double mutationRate) { | ||
this.mutationRate = mutationRate; | ||
} | ||
|
||
public int getMaxPopulation() { | ||
return maxPopulation; | ||
} | ||
|
||
public void setMaxPopulation(int maxPopulation) { | ||
this.maxPopulation = maxPopulation; | ||
} | ||
|
||
public ArrayList<DNA> getPopulation() { | ||
return this.population; | ||
} | ||
|
||
public void setPopulation(ArrayList<DNA> population) { | ||
this.population = population; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package main; | ||
|
||
import AI.Population; | ||
|
||
/** | ||
* Created by Nicola on 6/16/2017. | ||
*/ | ||
public class Main { | ||
final static String target = "Test sentence"; | ||
final static int populationDimension = 500; | ||
final static double mutationRate = 0.01; | ||
|
||
public static void main(String[] args) { | ||
int i = 0; | ||
double e, s; | ||
//Population lifecycle | ||
Population p = new Population(mutationRate, populationDimension, target); | ||
p.initPopulation(); | ||
|
||
s = System.currentTimeMillis(); | ||
while (true) { | ||
//TODO definitely not the best way! | ||
try { | ||
System.out.print("Generation: " + ++i + "\t"); | ||
String result = p.naturalSelection(); | ||
|
||
|
||
if (result != null) { | ||
break; | ||
} | ||
} catch (ClassCastException ex) { | ||
//TODO that catch! | ||
break; | ||
} | ||
} | ||
e = System.currentTimeMillis(); | ||
System.out.println("Execution time: " + (e - s)/1000 + " seconds" + "\tgenerations: " + i); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package tests; | ||
|
||
import AI.DNA; | ||
import AI.Population; | ||
import org.junit.Test; | ||
|
||
import java.util.ArrayList; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
/** | ||
* Created by Nicola on 6/16/2017. | ||
*/ | ||
public class PopulationTest { | ||
//Population p = new Population(new ArrayList<DNA>()); | ||
// @Test | ||
// public void calcIndividualFitness() throws Exception { | ||
// } | ||
|
||
|
||
//Can't be used since there's randomness in the code, given by | ||
//mutation rate | ||
// @Test | ||
// public void reproduce_oddLengthDNA_sameParent() throws Exception { | ||
// DNA d1 = new DNA("This is a test!"); | ||
// assertEquals("This is a test!", p.reproduce(d1, d1).getGenes()); | ||
// } | ||
// | ||
// @Test | ||
// public void reproduce_evenLengthDNA_sameParent() throws Exception { | ||
// DNA d1 = new DNA("This is a test"); | ||
// assertEquals("This is a test", p.reproduce(d1, d1).getGenes()); | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package util; | ||
|
||
import java.util.ArrayList; | ||
import java.util.concurrent.ThreadLocalRandom; | ||
|
||
/** | ||
* Created by Nicola on 6/16/2017. | ||
*/ | ||
public class RandomUtil { | ||
public static int min_maxBoundedInt(int min, int max) { | ||
return ThreadLocalRandom.current().nextInt(min, max + 1); | ||
} | ||
|
||
public static char randomChar() { | ||
return (char) min_maxBoundedInt(32, 122); | ||
} | ||
|
||
public static String randomString(int length) { | ||
StringBuilder sb = new StringBuilder(); | ||
for (int i = 0; i < length; i++) { | ||
sb.append(randomChar()); | ||
} | ||
return sb.toString(); | ||
} | ||
|
||
//TODO consider improving this algorithm | ||
public static boolean extractWithRate(double rate){ | ||
rate *= 100; | ||
ArrayList<Integer> l = new ArrayList(); | ||
|
||
//Fill arrays | ||
for(int i = 0; i<100 - rate; i++) l.add(0); | ||
for(int i = 0; i<rate; i++) l.add(1); | ||
return (l.get(min_maxBoundedInt(0, l.size()-1)) == 1) ? true : false; | ||
} | ||
} |