[tor-commits] [metrics-tasks/master] Add code for task 3276.

karsten at torproject.org karsten at torproject.org
Tue May 24 07:34:15 UTC 2011


commit 1147c7170f4d44ee5f0ed6c785e655537356945c
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Tue May 24 09:33:51 2011 +0200

    Add code for task 3276.
---
 task-3276/.gitignore                    |    4 +++
 task-3276/ExtractOnionKeyLifetimes.java |   37 +++++++++++++++++++++++++++++
 task-3276/ParseServerDescriptors.java   |   39 +++++++++++++++++++++++++++++++
 task-3276/README                        |   25 +++++++++++++++++++
 task-3276/onion-key-lifetimes.R         |   15 ++++++++++++
 5 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/task-3276/.gitignore b/task-3276/.gitignore
new file mode 100644
index 0000000..c7cc80b
--- /dev/null
+++ b/task-3276/.gitignore
@@ -0,0 +1,4 @@
+*.csv
+Rplots.pdf
+*.png
+
diff --git a/task-3276/ExtractOnionKeyLifetimes.java b/task-3276/ExtractOnionKeyLifetimes.java
new file mode 100644
index 0000000..4a210b1
--- /dev/null
+++ b/task-3276/ExtractOnionKeyLifetimes.java
@@ -0,0 +1,37 @@
+import java.io.*;
+import java.text.*;
+import java.util.*;
+public class ExtractOnionKeyLifetimes {
+  public static void main(String[] args) throws Exception {
+    BufferedReader br = new BufferedReader(new FileReader(
+        "sorted-2011-05.csv"));
+    String line, lastFingerprint = null, firstPublished = null,
+        lastPublished = null, lastOnionKey = null;
+    SimpleDateFormat formatter = new SimpleDateFormat(
+        "yyyy-MM-dd HH:mm:ss");
+    formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+    while ((line = br.readLine()) != null) {
+      String[] parts = line.split(",");
+      String fingerprint = parts[0];
+      String published = parts[1];
+      String onionKey = parts[2];
+      if (lastFingerprint == null ||
+          !lastFingerprint.equals(fingerprint) ||
+          !lastOnionKey.equals(onionKey)) {
+        if (firstPublished != null &&
+            !firstPublished.equals(lastPublished)) {
+          long interval = formatter.parse(lastPublished).getTime()
+              - formatter.parse(firstPublished).getTime();
+          System.out.println(lastFingerprint + "," + firstPublished + ","
+              + lastPublished + "," + (interval / 1000L));
+        }
+        firstPublished = published;
+      }
+      lastFingerprint = fingerprint;
+      lastPublished = published;
+      lastOnionKey = onionKey;
+    }
+    br.close();
+  }
+}
+
diff --git a/task-3276/ParseServerDescriptors.java b/task-3276/ParseServerDescriptors.java
new file mode 100644
index 0000000..2810d53
--- /dev/null
+++ b/task-3276/ParseServerDescriptors.java
@@ -0,0 +1,39 @@
+import java.io.*;
+import java.util.*;
+public class ParseServerDescriptors {
+  public static void main(String[] args) throws Exception {
+    Stack<File> files = new Stack<File>();
+    files.add(new File(args[0]));
+    while (!files.isEmpty()) {
+      File file = files.pop();
+      if (file.isDirectory()) {
+        for (File f : file.listFiles()) {
+          files.add(f);
+        }
+      } else {
+        BufferedReader br = new BufferedReader(new FileReader(file));
+        String line, published = null, fingerprint = null;
+        boolean readOnionKey = false;
+        StringBuilder onionKey = new StringBuilder();
+        while ((line = br.readLine()) != null) {
+          if (readOnionKey && !line.startsWith("-----")) {
+            onionKey.append(line);
+          } else if (line.startsWith("published ")) {
+            published = line.substring("published ".length());
+          } else if (line.startsWith("opt fingerprint")) {
+            fingerprint = line.substring("opt fingerprint ".length()).
+                replaceAll(" ", "");
+          } else if (line.equals("onion-key")) {
+            readOnionKey = true;
+          } else if (line.equals("-----END RSA PUBLIC KEY-----")) {
+            readOnionKey = false;
+          }
+        }
+        br.close();
+        System.out.println(fingerprint + "," + published + ","
+            + onionKey.toString());
+      }
+    }
+  }
+}
+
diff --git a/task-3276/README b/task-3276/README
new file mode 100644
index 0000000..8725044
--- /dev/null
+++ b/task-3276/README
@@ -0,0 +1,25 @@
+Find out onion key lifetime from server descriptors:
+
+First, parse fingerprints, publication times, and onion keys from server
+descriptors to make subsequent analyses faster:
+
+  $ javac ParseServerDescriptors.java
+  $ java ParseServerDescriptors server-descriptor/2011/05 \
+      > parsed-2011-05.csv
+
+Sort the output by fingerprint, then by publication time:
+
+  $ sort parsed-2011-05.csv > sorted-2011-05.csv
+
+Extract first and last publication times of onion keys that we saw at
+least twice.  Also include the fingerprint and calculate the number of
+seconds between the two timestamps:
+
+  $ javac ExtractOnionKeyLifetimes.java
+  $ java ExtractOnionKeyLifetimes.java > onion-key-lifetimes.csv
+
+Plot an ECDF and print out the onion keys that were in use for at least 10
+days:
+
+  $ R --slave -f onion-key-lifetimes.R
+
diff --git a/task-3276/onion-key-lifetimes.R b/task-3276/onion-key-lifetimes.R
new file mode 100644
index 0000000..182706c
--- /dev/null
+++ b/task-3276/onion-key-lifetimes.R
@@ -0,0 +1,15 @@
+library(ggplot2)
+data <- read.csv("onion-key-lifetimes.csv",
+  col.names = c("fingerprint", "start", "end", "length"),
+  stringsAsFactors = FALSE)
+print(data[data$length >= 10 * 24 * 60 * 60, ])
+data <- sort(data$length)
+data <- data.frame(x = data / (24 * 60 * 60), y = 1:length(data))
+ggplot(data, aes(x = x, y = y)) +
+geom_line() +
+scale_y_continuous("Cumulative number of onion keys\n") +
+scale_x_continuous(paste("\nTime between first and last publication of",
+  "the same onion key in May 2011 in days"))
+ggsave(filename = "onion-key-lifetimes.png", width = 8, height = 5,
+  dpi = 72)
+



More information about the tor-commits mailing list