|
@@ -0,0 +1,259 @@
|
|
|
+package analyzer.tests;
|
|
|
+
|
|
|
+import analyzer.Analyzer;
|
|
|
+import analyzer.ClientLogParser;
|
|
|
+import analyzer.ServerLogParser;
|
|
|
+import analyzer.models.Client;
|
|
|
+import analyzer.models.Hashtag;
|
|
|
+import analyzer.models.User;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.FileReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.Future;
|
|
|
+
|
|
|
+/**
|
|
|
+ * This class evaluates results of the attacks on sets of subjects.
|
|
|
+ */
|
|
|
+public class Accuracy {
|
|
|
+ private static final int threadPoolSize = 8;
|
|
|
+
|
|
|
+ private static final int acceptRangeClientSet = 5;
|
|
|
+ private static final int acceptRangeHashtagSet = 5;
|
|
|
+
|
|
|
+ private static int counter;
|
|
|
+ private static int totalHashtags = 1000;
|
|
|
+ private static int totalClients = 1000;
|
|
|
+ private static final int clientThreshold = 5;
|
|
|
+
|
|
|
+ private static volatile int correct = 0;
|
|
|
+ private static volatile int averageRounds = 0;
|
|
|
+ private static volatile int averagePosts = 0;
|
|
|
+
|
|
|
+ public static final String boundnamesPath = "C:\\Users\\Admin\\Desktop\\Skripts\\Thesis\\Repo\\local\\vm-mount\\logs\\" + Analyzer.logType + Analyzer.clientNo + "\\boundnames.txt" ;
|
|
|
+ public static final List<String> identifiedLinks = new ArrayList<>();
|
|
|
+
|
|
|
+ private static Analyzer A;
|
|
|
+
|
|
|
+ public static void main(String[] args) throws InterruptedException, ExecutionException {
|
|
|
+ A = new Analyzer();
|
|
|
+ //hashtagTraceAccuracyUserUnknown();
|
|
|
+ clientTraceAccuracyUserUnknown();
|
|
|
+ //clientTraceAccuracyUserKnown();
|
|
|
+ }
|
|
|
+
|
|
|
+ //Step: most popular hashtags -> for each hashtag calculate points -> for each client intersect sets -> for each client check result
|
|
|
+ private static void hashtagTraceAccuracyUserUnknown() throws InterruptedException, ExecutionException {
|
|
|
+ List<Hashtag> hashtagList = new ArrayList<>(ServerLogParser.hashtags.values());
|
|
|
+ hashtagList.sort((h1, h2) -> Integer.compare(h2.getTotalPosts(), h1.getTotalPosts()));
|
|
|
+
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
|
|
|
+ List<Future<?>> tasks = new ArrayList<>();
|
|
|
+ totalHashtags = Math.min(totalHashtags, ServerLogParser.hashtags.values().size());
|
|
|
+ for(int i = 0; i < totalHashtags; i++) {
|
|
|
+ Future<?> task = executor.submit(new CheckHashtagTask(hashtagList.get(i)));
|
|
|
+ tasks.add(task);
|
|
|
+ }
|
|
|
+ for(Future<?> task : tasks)
|
|
|
+ task.get();
|
|
|
+ executor.shutdown();
|
|
|
+ printResult(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Step: set intersection -> calculate point ->
|
|
|
+ private static void clientTraceAccuracyUserUnknown() throws InterruptedException, ExecutionException {
|
|
|
+ List<Client> clientList = createClientSet(totalClients);
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
|
|
|
+ List<Future<?>> tasks = new ArrayList<>();
|
|
|
+
|
|
|
+ totalClients = Math.min(totalClients, clientList.size());
|
|
|
+ for(int i = 0; i < totalClients; i++) {
|
|
|
+ Future<?> task = executor.submit(new CheckClientTask(clientList.get(i)));
|
|
|
+ tasks.add(task);
|
|
|
+ }
|
|
|
+ for(Future<?> task : tasks){
|
|
|
+ task.get();
|
|
|
+ counter++;
|
|
|
+ float progress = (float) Math.round(((float) counter / (float) totalHashtags) * 1000.0F) / 10.0F;
|
|
|
+ System.out.print("\r");
|
|
|
+ System.out.print(progress + " % done");
|
|
|
+ }
|
|
|
+ executor.shutdown();
|
|
|
+ printResult(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void clientTraceAccuracyUserKnown() throws InterruptedException, ExecutionException {
|
|
|
+ List<Client> clientList = createClientSet(totalClients);
|
|
|
+ System.out.println("clientList size " + clientList.size());
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
|
|
|
+ List<Future<?>> tasks = new ArrayList<>();
|
|
|
+
|
|
|
+ totalClients = Math.min(totalClients, clientList.size());
|
|
|
+ for(int i = 0; i < totalClients; i++) {
|
|
|
+ Future<?> task = executor.submit(new CheckClientTaskUserKnown(clientList.get(i)));
|
|
|
+ tasks.add(task);
|
|
|
+ }
|
|
|
+ for(Future<?> task : tasks){
|
|
|
+ task.get();
|
|
|
+ counter++;
|
|
|
+ float progress = (float) Math.round(((float) counter / (float) totalHashtags) * 1000.0F) / 10.0F;
|
|
|
+ System.out.print("\r");
|
|
|
+ System.out.print(progress + " % done");
|
|
|
+ }
|
|
|
+ executor.shutdown();
|
|
|
+ printResult(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkClientHashtagLink(Client client, Hashtag hashtag) throws IOException {
|
|
|
+ FileReader fr = new FileReader(boundnamesPath);
|
|
|
+ BufferedReader br= new BufferedReader(fr);
|
|
|
+ String line;
|
|
|
+ while((line = br.readLine()) != null) {
|
|
|
+ String[] elements = line.trim().split("\t");//userID client-ID
|
|
|
+
|
|
|
+ if(elements[1].equals(client.getId())) {
|
|
|
+ if(ServerLogParser.users.get(String.valueOf(elements[0])).getHashtags().containsKey(hashtag)) {
|
|
|
+ br.close();
|
|
|
+ identifiedLinks.add(client.getId() + "-" + hashtag.getName());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ br.close();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean checkClientUserLink(Client client, User user) throws IOException {
|
|
|
+ FileReader fr = new FileReader(boundnamesPath);
|
|
|
+ BufferedReader br= new BufferedReader(fr);
|
|
|
+ String line;
|
|
|
+ while((line = br.readLine()) != null) {
|
|
|
+ String[] elements = line.trim().split("\t");//userID client-ID
|
|
|
+
|
|
|
+ if(String.valueOf(elements[0]).equals(user.getId()))
|
|
|
+ return elements[1].equals(client.getId());
|
|
|
+ }
|
|
|
+ System.out.println("User not found");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<Client> createClientSet(int num) {
|
|
|
+ List<Client> result = new ArrayList<>();
|
|
|
+ for(Client c : ClientLogParser.clients.values()) {
|
|
|
+ if(result.size() == num)
|
|
|
+ break;
|
|
|
+ else {
|
|
|
+ if(c.getTotalPosts() >= Accuracy.clientThreshold)
|
|
|
+ result.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(result.size() < num)
|
|
|
+ totalClients = result.size();
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private static void printResult(boolean userKnown) {
|
|
|
+ System.out.println();
|
|
|
+ if(!userKnown) {
|
|
|
+ //System.out.println("acceptRangeClientSet: " + acceptRangeClientSet);
|
|
|
+ //System.out.println("acceptRangeHashtagSet: " + acceptRangeHashtagSet);
|
|
|
+ System.out.println("clientThreshold: " + clientThreshold);
|
|
|
+ double result = ((double) correct / (double) totalClients) * 100.00;
|
|
|
+ System.out.println(result + " % of " + totalClients);
|
|
|
+ System.out.println("average most ranked: " + (double) averagePosts/(double)totalClients);
|
|
|
+ System.out.print(identifiedLinks.size() + " identified links: ");
|
|
|
+ for(String s: identifiedLinks) {
|
|
|
+ System.out.print(s + " ");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ double result = ((double) averageRounds / (double) totalClients);
|
|
|
+ System.out.println(result + " rounds of " + totalClients);
|
|
|
+ }
|
|
|
+ System.out.println();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static synchronized void incrementCorrect() {
|
|
|
+ correct++;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static synchronized void addToAverageRounds(int n) {
|
|
|
+ averageRounds += n;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static synchronized void addToAveragePosts(int n) {
|
|
|
+ averagePosts += n;
|
|
|
+ }
|
|
|
+
|
|
|
+ private record CheckHashtagTask(Hashtag hashtag) implements Runnable {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ List<Map.Entry<Client, Integer>> lst = A.calculatePointsAllClients(hashtag, acceptRangeClientSet, false);
|
|
|
+ for(int i = 0; i < acceptRangeClientSet; i++) {
|
|
|
+ for(Map.Entry<String, Integer> e: A.intersectHashtags(lst.get(i).getKey(), acceptRangeHashtagSet, false))
|
|
|
+ if(e.getKey().equals(hashtag.getName())) {
|
|
|
+ if(checkClientHashtagLink(lst.get(i).getKey(), hashtag)) {
|
|
|
+ incrementCorrect();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ counter++;
|
|
|
+ float progress = (float) Math.round(((float) counter / (float) totalHashtags) * 1000.0F) / 10.0F;
|
|
|
+ System.out.print("\r");
|
|
|
+ System.out.print(progress + " % done");
|
|
|
+ } catch (InterruptedException | IOException | ExecutionException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private record CheckClientTask(Client client) implements Runnable {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ List<Map.Entry<String, Integer>> intersection = A.intersectHashtags(client, 1, false);
|
|
|
+ intersection.removeIf(e -> e.getValue() < 0);
|
|
|
+ Hashtag[] hashtags = new Hashtag[intersection.size()];
|
|
|
+ for(int i = 0; i < hashtags.length; i++)
|
|
|
+ hashtags[i] = ServerLogParser.hashtags.get(intersection.get(i).getKey());
|
|
|
+
|
|
|
+ List<Map.Entry<Hashtag, Integer>> points = A.calculatePointsGivenHashtags(client, hashtags, 1, false);
|
|
|
+ addToAveragePosts(points.size());
|
|
|
+ for(Map.Entry<Hashtag, Integer> e : points) {
|
|
|
+ boolean identified = checkClientHashtagLink(client, e.getKey());
|
|
|
+ if(identified){
|
|
|
+ incrementCorrect();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (InterruptedException | ExecutionException | IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private record CheckClientTaskUserKnown(Client client) implements Runnable {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ int rounds = A.intersectUsers(client, 1, false);
|
|
|
+ if (rounds == -1) {
|
|
|
+ totalClients--;
|
|
|
+ } else {
|
|
|
+ addToAverageRounds(rounds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|