33import java .io .BufferedInputStream ;
44import java .io .Console ;
55import java .io .DataInputStream ;
6+ import java .io .File ;
67import java .io .FileInputStream ;
7- import java .io .RandomAccessFile ;
88import java .nio .charset .Charset ;
99import java .security .MessageDigest ;
1010import java .util .Scanner ;
@@ -15,11 +15,17 @@ public class PasswordLookup {
1515
1616 public static void main (String ... args ) throws Exception {
1717 if (args .length != 1 ) {
18- System .out .println ("Usage: java " + PasswordLookup .class .getName () + " <filterFileName > \n "
18+ System .out .println ("Usage: java " + PasswordLookup .class .getName () + " <filterFile > \n "
1919 + "Requires a filter file generated by " + BuildFilterFile .class .getName ());
2020 return ;
2121 }
22- String filterFileName = args [0 ];
22+ String filterFile = args [0 ];
23+ DataInputStream in = openFile (filterFile , new File (filterFile ).length () - (8 << BuildFilterFile .SEGMENT_BITS ));
24+ long [] segmentStarts = new long [1 << BuildFilterFile .SEGMENT_BITS ];
25+ for (int i = 0 ; i < segmentStarts .length ; i ++) {
26+ segmentStarts [i ] = in .readLong ();
27+ }
28+ in .close ();
2329 Scanner scanner = new Scanner (System .in );
2430 while (true ) {
2531 Console console = System .console ();
@@ -33,13 +39,14 @@ public static void main(String... args) throws Exception {
3339 if (password .length () == 0 ) {
3440 break ;
3541 }
36- testPassword (filterFileName , password );
42+ testPassword (filterFile , segmentStarts , password );
3743 }
3844 scanner .close ();
3945 }
4046
41- private static void testPassword (String filterFileName , String password ) throws Exception {
42- // it's unclear which character set was used; ASCII gave good results, as umlauts are converted to '?'
47+ private static void testPassword (String filterFile , long [] segmentStarts , String password ) throws Exception {
48+ // it's unclear which character set was used; ASCII gave good results, as
49+ // umlauts are converted to '?'
4350 byte [] passwordBytes = password .getBytes (Charset .forName ("ASCII" ));
4451 MessageDigest md = MessageDigest .getInstance ("SHA-1" );
4552 byte [] sha1 = md .digest (passwordBytes );
@@ -49,19 +56,8 @@ private static void testPassword(String filterFileName, String password) throws
4956 }
5057 // set the lowest bit to 0
5158 long key = hash ^ (hash & 1 );
52- RandomAccessFile f = new RandomAccessFile (filterFileName , "r" );
5359 int segment = (int ) (key >>> (64 - BuildFilterFile .SEGMENT_BITS ));
54- f .seek (segment * 8 );
55- long skip = f .readLong ();
56- f .close ();
57- DataInputStream in = new DataInputStream (new BufferedInputStream (new FileInputStream (filterFileName )));
58- while (skip > 0 ) {
59- long skipped = in .skip (skip );
60- if (skipped <= 0 ) {
61- break ;
62- }
63- skip -= skipped ;
64- }
60+ DataInputStream in = openFile (filterFile , segmentStarts [segment ]);
6561 XorPlus8 filter = new XorPlus8 (in );
6662 in .close ();
6763 if (filter .mayContain (key )) {
@@ -73,4 +69,16 @@ private static void testPassword(String filterFileName, String password) throws
7369 }
7470 }
7571
72+ static DataInputStream openFile (String fileName , long skip ) throws Exception {
73+ DataInputStream in = new DataInputStream (new BufferedInputStream (new FileInputStream (fileName )));
74+ while (skip > 0 ) {
75+ long skipped = in .skip (skip );
76+ if (skipped <= 0 ) {
77+ break ;
78+ }
79+ skip -= skipped ;
80+ }
81+ return in ;
82+ }
83+
7684}
0 commit comments