commit 1147c7170f4d44ee5f0ed6c785e655537356945c Author: Karsten Loesing karsten.loesing@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) +
tor-commits@lists.torproject.org