/
BFDictionaryDirective.java
executable file
·66 lines (55 loc) · 2.3 KB
/
BFDictionaryDirective.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package co.insecurity.policy.directive;
import orestes.bloomfilter.BloomFilter;
import orestes.bloomfilter.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ConcurrentModificationException;
public class BFDictionaryDirective implements Directive<String> {
private static final Logger LOG = LoggerFactory.getLogger(BFDictionaryDirective.class);
private static final String DEFAULT_DICTIONARY = "passwords.dat";
private final BloomFilter<String> filter;
public BFDictionaryDirective() throws IOException {
this(Dictionary.fromResource(DEFAULT_DICTIONARY));
}
public BFDictionaryDirective(Dictionary dictionary) throws IOException {
filter = new FilterBuilder(dictionary.getNumWords(), 0.001)
.buildBloomFilter();
loadDictionary(dictionary);
LOG.debug("Instantiated new directive: {}", this.toString());
}
public BFDictionaryDirective(BloomFilter<String> filter) {
this.filter = filter;
LOG.debug("Instantiated new directive: {}", this.toString());
}
public void loadDictionary(Dictionary dictionary) throws IOException {
LOG.debug("Loading {} into filter", dictionary);
int numExpected = filter.getExpectedElements();
int numAdded = 0;
try (BufferedReader reader = dictionary.getReader()) {
String word = null;
while ((word = reader.readLine()) != null) {
if (filter.add(word))
numAdded++;
else
LOG.debug("Not loaded into filter (may be duplicate): {}", word);
if (numAdded > numExpected) {
String msg = String.format("Added %d words but expected %d. Did the data file change?",
numAdded, numExpected);
LOG.error(msg);
throw new ConcurrentModificationException(msg);
}
}
}
LOG.debug("Successfully loaded {} words into filter", numAdded);
}
@Override
public boolean isMet(String s) {
return !filter.contains(s);
}
@Override
public String toString() {
return String.format("[BFDictionaryDirective[%s]", filter.asString());
}
}