package analyzer; 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 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 hashtagList = new ArrayList<>(ServerLogParser.hashtags.values()); hashtagList.sort((h1, h2) -> Integer.compare(h2.getTotalPosts(), h1.getTotalPosts())); ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); List> 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 clientList = createClientSet(totalClients); ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); List> 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 clientList = createClientSet(totalClients); System.out.println("clientList size " + clientList.size()); ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); List> 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(Long.parseLong(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(Long.parseLong(elements[0]) == user.getId()) return elements[1].equals(client.getId()); } System.out.println("User not found"); return false; } private static List createClientSet(int num) { List 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> lst = A.calculatePointsAllClients(hashtag, acceptRangeClientSet, false); for(int i = 0; i < acceptRangeClientSet; i++) { for(Map.Entry 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> 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> points = A.calculatePointsGivenHashtags(client, hashtags, 1, false); addToAveragePosts(points.size()); for(Map.Entry 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); } } } }