wordlist 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitignore +6 -3
  4. data/ChangeLog.md +45 -1
  5. data/Gemfile +13 -0
  6. data/LICENSE.txt +1 -3
  7. data/README.md +266 -61
  8. data/Rakefile +7 -32
  9. data/benchmarks.rb +115 -0
  10. data/bin/wordlist +4 -7
  11. data/data/stop_words/ar.txt +104 -0
  12. data/data/stop_words/bg.txt +259 -0
  13. data/data/stop_words/bn.txt +363 -0
  14. data/data/stop_words/ca.txt +126 -0
  15. data/data/stop_words/cs.txt +138 -0
  16. data/data/stop_words/da.txt +101 -0
  17. data/data/stop_words/de.txt +129 -0
  18. data/data/stop_words/el.txt +79 -0
  19. data/data/stop_words/en.txt +175 -0
  20. data/data/stop_words/es.txt +178 -0
  21. data/data/stop_words/eu.txt +98 -0
  22. data/data/stop_words/fa.txt +332 -0
  23. data/data/stop_words/fi.txt +747 -0
  24. data/data/stop_words/fr.txt +116 -0
  25. data/data/stop_words/ga.txt +109 -0
  26. data/data/stop_words/gl.txt +160 -0
  27. data/data/stop_words/he.txt +499 -0
  28. data/data/stop_words/hi.txt +97 -0
  29. data/data/stop_words/hr.txt +179 -0
  30. data/data/stop_words/hu.txt +35 -0
  31. data/data/stop_words/hy.txt +45 -0
  32. data/data/stop_words/id.txt +357 -0
  33. data/data/stop_words/it.txt +134 -0
  34. data/data/stop_words/ja.txt +44 -0
  35. data/data/stop_words/ko.txt +677 -0
  36. data/data/stop_words/ku.txt +63 -0
  37. data/data/stop_words/lt.txt +507 -0
  38. data/data/stop_words/lv.txt +163 -0
  39. data/data/stop_words/mr.txt +99 -0
  40. data/data/stop_words/nl.txt +48 -0
  41. data/data/stop_words/no.txt +172 -0
  42. data/data/stop_words/pl.txt +138 -0
  43. data/data/stop_words/pt.txt +147 -0
  44. data/data/stop_words/ro.txt +281 -0
  45. data/data/stop_words/ru.txt +421 -0
  46. data/data/stop_words/sk.txt +173 -0
  47. data/data/stop_words/sv.txt +386 -0
  48. data/data/stop_words/th.txt +115 -0
  49. data/data/stop_words/tr.txt +114 -0
  50. data/data/stop_words/uk.txt +28 -0
  51. data/data/stop_words/ur.txt +513 -0
  52. data/data/stop_words/zh.txt +125 -0
  53. data/gemspec.yml +4 -10
  54. data/lib/wordlist/abstract_wordlist.rb +24 -0
  55. data/lib/wordlist/builder.rb +170 -138
  56. data/lib/wordlist/cli.rb +458 -0
  57. data/lib/wordlist/compression/reader.rb +72 -0
  58. data/lib/wordlist/compression/writer.rb +80 -0
  59. data/lib/wordlist/exceptions.rb +31 -0
  60. data/lib/wordlist/file.rb +176 -0
  61. data/lib/wordlist/format.rb +38 -0
  62. data/lib/wordlist/lexer/lang.rb +32 -0
  63. data/lib/wordlist/lexer/stop_words.rb +68 -0
  64. data/lib/wordlist/lexer.rb +218 -0
  65. data/lib/wordlist/list_methods.rb +462 -0
  66. data/lib/wordlist/modifiers/capitalize.rb +45 -0
  67. data/lib/wordlist/modifiers/downcase.rb +45 -0
  68. data/lib/wordlist/modifiers/gsub.rb +51 -0
  69. data/lib/wordlist/modifiers/modifier.rb +44 -0
  70. data/lib/wordlist/modifiers/mutate.rb +133 -0
  71. data/lib/wordlist/modifiers/mutate_case.rb +25 -0
  72. data/lib/wordlist/modifiers/sub.rb +97 -0
  73. data/lib/wordlist/modifiers/tr.rb +71 -0
  74. data/lib/wordlist/modifiers/upcase.rb +45 -0
  75. data/lib/wordlist/modifiers.rb +8 -0
  76. data/lib/wordlist/operators/binary_operator.rb +38 -0
  77. data/lib/wordlist/operators/concat.rb +47 -0
  78. data/lib/wordlist/operators/intersect.rb +55 -0
  79. data/lib/wordlist/operators/operator.rb +29 -0
  80. data/lib/wordlist/operators/power.rb +72 -0
  81. data/lib/wordlist/operators/product.rb +50 -0
  82. data/lib/wordlist/operators/subtract.rb +54 -0
  83. data/lib/wordlist/operators/unary_operator.rb +29 -0
  84. data/lib/wordlist/operators/union.rb +61 -0
  85. data/lib/wordlist/operators/unique.rb +52 -0
  86. data/lib/wordlist/operators.rb +7 -0
  87. data/lib/wordlist/unique_filter.rb +40 -61
  88. data/lib/wordlist/version.rb +1 -1
  89. data/lib/wordlist/words.rb +71 -0
  90. data/lib/wordlist.rb +103 -2
  91. data/spec/abstract_list_spec.rb +18 -0
  92. data/spec/builder_spec.rb +220 -76
  93. data/spec/cli_spec.rb +801 -0
  94. data/spec/compression/reader_spec.rb +137 -0
  95. data/spec/compression/writer_spec.rb +194 -0
  96. data/spec/file_spec.rb +258 -0
  97. data/spec/fixtures/wordlist.txt +15 -0
  98. data/spec/fixtures/wordlist.txt.bz2 +0 -0
  99. data/spec/fixtures/wordlist.txt.gz +0 -0
  100. data/spec/fixtures/wordlist.txt.xz +0 -0
  101. data/spec/fixtures/wordlist_with_ambiguous_format +3 -0
  102. data/spec/fixtures/wordlist_with_comments.txt +19 -0
  103. data/spec/fixtures/wordlist_with_empty_lines.txt +19 -0
  104. data/spec/format_spec.rb +50 -0
  105. data/spec/helpers/text.rb +3 -3
  106. data/spec/helpers/wordlist.rb +2 -2
  107. data/spec/lexer/lang_spec.rb +70 -0
  108. data/spec/lexer/stop_words_spec.rb +77 -0
  109. data/spec/lexer_spec.rb +652 -0
  110. data/spec/list_methods_spec.rb +181 -0
  111. data/spec/modifiers/capitalize_spec.rb +27 -0
  112. data/spec/modifiers/downcase_spec.rb +27 -0
  113. data/spec/modifiers/gsub_spec.rb +59 -0
  114. data/spec/modifiers/modifier_spec.rb +20 -0
  115. data/spec/modifiers/mutate_case_spec.rb +46 -0
  116. data/spec/modifiers/mutate_spec.rb +39 -0
  117. data/spec/modifiers/sub_spec.rb +98 -0
  118. data/spec/modifiers/tr_spec.rb +46 -0
  119. data/spec/modifiers/upcase_spec.rb +27 -0
  120. data/spec/operators/binary_operator_spec.rb +19 -0
  121. data/spec/operators/concat_spec.rb +26 -0
  122. data/spec/operators/intersect_spec.rb +37 -0
  123. data/spec/operators/operator_spec.rb +16 -0
  124. data/spec/operators/power_spec.rb +57 -0
  125. data/spec/operators/product_spec.rb +39 -0
  126. data/spec/operators/subtract_spec.rb +37 -0
  127. data/spec/operators/union_spec.rb +37 -0
  128. data/spec/operators/unique_spec.rb +25 -0
  129. data/spec/spec_helper.rb +2 -1
  130. data/spec/unique_filter_spec.rb +108 -18
  131. data/spec/wordlist_spec.rb +55 -3
  132. data/spec/words_spec.rb +41 -0
  133. metadata +183 -120
  134. data/lib/wordlist/builders/website.rb +0 -216
  135. data/lib/wordlist/builders.rb +0 -1
  136. data/lib/wordlist/flat_file.rb +0 -47
  137. data/lib/wordlist/list.rb +0 -162
  138. data/lib/wordlist/mutator.rb +0 -113
  139. data/lib/wordlist/parsers.rb +0 -74
  140. data/lib/wordlist/runners/list.rb +0 -116
  141. data/lib/wordlist/runners/runner.rb +0 -67
  142. data/lib/wordlist/runners.rb +0 -2
  143. data/scripts/benchmark +0 -59
  144. data/scripts/text/comedy_of_errors.txt +0 -4011
  145. data/spec/flat_file_spec.rb +0 -25
  146. data/spec/list_spec.rb +0 -58
  147. data/spec/mutator_spec.rb +0 -43
  148. data/spec/parsers_spec.rb +0 -118
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 98d7c15c0542442692f3ddd9eb1903b717ee9dc99c38744efa035140d3387c3b
4
+ data.tar.gz: 3a343f015e734d5b48caaaa0379cfab7b082235f21c14048de72bc7aba0658da
5
+ SHA512:
6
+ metadata.gz: c6ad1af333afa7b2599729db8ff761d236ab7b70c37a0855f888debf547818fd1698b5efaa064742107f5003621fcab9efc6a3e101a8241c1ef7ea68b80344b6
7
+ data.tar.gz: 920e99dac9529db87d16394d94ccafcdefd45b64b6e8f9dc4664dc95846c6cfa5d5910d119cfa146249e1d46325e7a07a1471ea061d15f53f4b1b6736d4bd16e
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on: [ push, pull_request ]
4
+
5
+ jobs:
6
+ tests:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby:
12
+ - 2.6
13
+ - 2.7
14
+ - 3.0
15
+ - jruby
16
+ - truffleruby
17
+ name: Ruby ${{ matrix.ruby }}
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - name: Set up Ruby
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ matrix.ruby }}
24
+ - name: Install dependencies
25
+ run: bundle install --jobs 4 --retry 3
26
+ - name: Run tests
27
+ run: bundle exec rake test
data/.gitignore CHANGED
@@ -1,6 +1,9 @@
1
- doc
2
- pkg
3
- tmp/*
1
+ /Gemfile.lock
2
+ /benchmarks
3
+ /coverage
4
+ /doc
5
+ /pkg
6
+ /tmp
4
7
  scripts/*_wordlist.txt
5
8
  .DS_Store
6
9
  .bundle
data/ChangeLog.md CHANGED
@@ -1,6 +1,50 @@
1
+ ### 1.0.0 / 2021-11-01
2
+
3
+ * Redesigned the API.
4
+ * Added {Wordlist::AbstractWordlist}.
5
+ * Added {Wordlist::ListMethods}.
6
+ * Added {Wordlist::Operators}.
7
+ * Added {Wordlist::Operators::Operator}.
8
+ * Added {Wordlist::Operators::UnaryOperator}.
9
+ * Added {Wordlist::Operators::BinaryOperator}.
10
+ * Added {Wordlist::Operators::Concat}.
11
+ * Added {Wordlist::Operators::Subtract}.
12
+ * Added {Wordlist::Operators::Product}.
13
+ * Added {Wordlist::Operators::Power}.
14
+ * Added {Wordlist::Operators::Union}.
15
+ * Added {Wordlist::Operators::Intersect}.
16
+ * Added {Wordlist::Operators::Unique}.
17
+ * Added {Wordlist::Modifiers}.
18
+ * Added {Wordlist::Modifiers::Modifier}.
19
+ * Added {Wordlist::Modifiers::Capitalize}.
20
+ * Added {Wordlist::Modifiers::Downcase}.
21
+ * Added {Wordlist::Modifiers::Upcase}.
22
+ * Added {Wordlist::Modifiers::Tr}.
23
+ * Added {Wordlist::Modifiers::Sub}.
24
+ * Added {Wordlist::Modifiers::Gsub}.
25
+ * Added {Wordlist::Modifiers::Mutate}.
26
+ * Added {Wordlist::Modifiers::MutateCase}.
27
+ * Added {Wordlist::Words}.
28
+ * Added {Wordlist::Format}.
29
+ * Added {Wordlist::Compression}.
30
+ * Added {Wordlist::Compression::Reader}.
31
+ * Added {Wordlist::Compression::Writer}.
32
+ * Added {Wordlist::File}.
33
+ * Added {Wordlist::Lexer}.
34
+ * Added {Wordlist::Lexer::StopWords}.
35
+ * Added {Wordlist::Builder}.
36
+ * Added {Wordlist::CLI}.
37
+ * Refactored {Wordlist::UniqueFilter} to only store Object hashes.
38
+ * Removed `Wordlist::List`.
39
+ * Removed `Wordlist::FlatFile`.
40
+ * Removed `Wordlist::Mutator` in favor of {Wordlist::Modifiers::Mutate}.
41
+ * Removed `Wordlist::Parsers` in favor of {Wordlist::Lexer}.
42
+ * Removed `Wordlist::Builders`.
43
+ * Removed `Wordlist::Runners`.
44
+
1
45
  ### 0.1.1 / 2012-06-11
2
46
 
3
- * Default {Wordlist::Builders::Website#proxy} to `Spidr.proxy`.
47
+ * Default `Wordlist::Builders::Website#proxy` to `Spidr.proxy`.
4
48
 
5
49
  ### 0.1.0 / 2009-08-31
6
50
 
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ gem 'rspec', '~> 3.0'
9
+ gem 'simplecov', '~> 0.20'
10
+ gem 'kramdown'
11
+ gem 'yard', '~> 0.9'
12
+ gem 'yard-spellcheck', require: false
13
+ end
data/LICENSE.txt CHANGED
@@ -1,6 +1,4 @@
1
- Wordlist - A Ruby library for generating and working with word-lists.
2
-
3
- Copyright (c) 2009-2012 Hal Brodigan
1
+ Copyright (c) 2009-2021 Hal Brodigan
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining
6
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,96 +1,301 @@
1
1
  # Wordlist
2
2
 
3
- * [Source](https://github.com/sophsec/wordlist#readme)
4
- * [Issues](https://github.com/sophsec/wordlist/issues)
5
- * [Email](mailto:postmodern.mod3 at gmail.com)
3
+ [![CI](https://github.com/postmodern/wordlist.rb/actions/workflows/ruby.yml/badge.svg)](https://github.com/postmodern/wordlist.rb/actions/workflows/ruby.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/wordlist.svg)](https://badge.fury.io/rb/wordlist)
5
+
6
+ * [Source](https://github.com/postmodern/wordlist.rb#readme)
7
+ * [Issues](https://github.com/postmodern/wordlist.rb/issues)
8
+ * [Documentation](https://rubydoc.info/gems/wordlist/frames)
6
9
 
7
10
  ## Description
8
11
 
9
- A Ruby library for generating and working with word-lists. Wordlist allows
10
- one to efficiently generate unique word-lists from arbitrary text or
11
- other sources, such as website content. Wordlist can also quickly enumerate
12
- through words within an existing word-list, applying multiple mutation
13
- rules to each word in the list.
12
+ Wordlist is a Ruby library for reading, manipulating, and creating wordlists,
13
+ efficiently.
14
14
 
15
15
  ## Features
16
16
 
17
- * Uses a bucket system of CRC32 hashes for efficient filtering of duplicate
18
- words.
19
- * Can build wordlists containing multi-word phrases.
20
- * Can build wordlists containing phrases containing a minimum and maximum
21
- number of words.
22
- * Supports adding mutation rules to a word-list, which are applied to
23
- words as the list is enumerated.
24
- * Supports building word-lists from arbitrary text.
25
- * Supports custom word-list builders:
26
- * Wordlist::Builders::Website: Build word-lists from website content.
27
- * Supports custom word-list formats:
28
- * Wordlist::FlatFile: Enumerates through the words in a flat-file
29
- word-list.
17
+ * Supports reading `.txt` wordlists, and `.txt.gz`, `.txt.bz2`, and `.txt.xz`
18
+ compressed wordlists.
19
+ * Supports building wordlists from arbitrary text. Also supports `.gz`, `.bz2,`
20
+ and `.xz` compression.
21
+ * Provides an advanced lexer for parsing text into words.
22
+ * Can parse/skip digits, special characters, whole numbers, acronyms.
23
+ * Can normalize case, apostrophes, and acronyms.
24
+ * Supports wordlist operations for combining multiple wordlists together.
25
+ * Supports wordlist manipulating to modify the words in the wordlist on the fly.
26
+ * Fast-ish
30
27
 
31
28
  ## Examples
32
29
 
33
- Build a word-list from arbitrary text:
30
+ ### Reading
31
+
32
+ Open a wordlist for reading:
33
+
34
+ ```ruby
35
+ wordlist = Wordlist.open("passwords.txt")
36
+ ```
37
+
38
+ Open a compressed wordlist for reading:
39
+
40
+ ```ruby
41
+ wordlist = Wordlist.open("rockyou.txt.gz")
42
+ ```
43
+
44
+ Enumerate through a wordlist:
45
+
46
+ ```ruby
47
+ wordlist.each do |word|
48
+ puts word
49
+ end
50
+ ```
51
+
52
+ Create an in-memory list of literal words:
53
+
54
+ ```ruby
55
+ words = Wordlist::Words["foo", "bar", "baz"]
56
+ ```
57
+
58
+ ### List Operations
59
+
60
+ Concat two wordlists together:
61
+
62
+ ```ruby
63
+ (wordlist1 + wordlist2).each do |word|
64
+ puts word
65
+ end
66
+ ```
67
+
68
+ Union two wordlists together:
69
+
70
+ ```ruby
71
+ (wordlist1 | wordlist2).each do |word|
72
+ puts word
73
+ end
74
+ ```
75
+
76
+ Subtract one wordlist from the other:
77
+
78
+ ```ruby
79
+ (wordlist1 - wordlist2).each do |word|
80
+ puts word
81
+ end
82
+ ```
83
+
84
+ Combine every word from `wordlist1` with the words from `wordlist2`:
85
+
86
+ ```ruby
87
+ (wordlist1 * wordlist2).each do |word|
88
+ puts word
89
+ end
90
+ ```
91
+
92
+ Combine the wordlist with itself multiple times:
93
+
94
+ ```ruby
95
+ (wordslist ** 3).each do |word|
96
+ puts word
97
+ end
98
+ ```
99
+
100
+ Filter out duplicates from multiple wordlists:
101
+
102
+ ```ruby
103
+ (wordlist1 + wordlist2 + wordlist3).uniq.each do |word|
104
+ puts word
105
+ end
106
+ ```
107
+
108
+ ### String Manipulation
109
+
110
+ Convert every word in a wordlist to lowercase:
111
+
112
+ ```ruby
113
+ wordlist.downcase.each do |word|
114
+ puts word
115
+ end
116
+ ```
117
+
118
+ Convert every word in a wordlist to UPPERCASE:
119
+
120
+ ```ruby
121
+ wordlist.upcase.each do |word|
122
+ puts word
123
+ end
124
+ ```
125
+
126
+ Capitalize every word in a wordlist:
34
127
 
35
- Wordlist::Builder.build('list.txt') do |builder|
36
- builder.parse(some_text)
37
- end
128
+ ```ruby
129
+ wordlist.capitalize.each do |word|
130
+ puts word
131
+ end
132
+ ```
38
133
 
39
- Build a word-list from another file:
134
+ Run `String#tr` on every word in a wordlist:
40
135
 
41
- Wordlist::Builder.build('list.txt') do |builder|
42
- builder.parse_file('some/file.txt')
43
- end
136
+ ```ruby
137
+ wordlist.tr('_','-').each do |word|
138
+ puts word
139
+ end
140
+ ```
44
141
 
45
- Build a word-list of phrases containing at most three words, from the
46
- arbitrary text:
142
+ Run `String#sub` on every word in a wordlist:
47
143
 
48
- Wordlist::Builder.build('list.txt', :max_words => 3) do |builder|
49
- builder.parse(some_text)
50
- end
144
+ ```ruby
145
+ wordlist.sub("fish","phish").each do |word|
146
+ puts word
147
+ end
148
+ ```
51
149
 
52
- Build a word-list from content off a website:
150
+ Run `String#gsub` on every word in a wordlist:
53
151
 
54
- require 'wordlist/builders/website'
152
+ ```ruby
153
+ wordlist.gsub(/\d+/,"").each do |word|
154
+ puts word
155
+ end
156
+ ```
55
157
 
56
- Wordlist::Builders::Website.build(
57
- 'list.txt',
58
- :host => 'www.example.com'
59
- )
158
+ Performs every possible mutation of each word in a wordlist:
60
159
 
61
- Enumerate through each word in a flat-file word-list:
160
+ ```ruby
161
+ wordlist.mutate(/[oae]/, {'o' => '0', 'a' => '@', 'e' => '3'}).each do |word|
162
+ puts word
163
+ end
164
+ ```
62
165
 
63
- list = Wordlist::FlatFile.new('list.txt')
64
- list.each_word do |word|
65
- puts word
66
- end
166
+ Enumerates over every possible case variation of every word in a wordlist:
67
167
 
68
- Enumerate through each unique word in a flat-file word-list:
168
+ ```ruby
169
+ wordlist.mutate_case.each do |word|
170
+ puts word
171
+ end
172
+ ```
69
173
 
70
- list.each_unique do |word|
71
- puts word
72
- end
174
+ ### Building a Wordlist
73
175
 
74
- Define mutation rules, and enumerate through each unique mutation of each
75
- unique word in the word-list:
176
+ ```ruby
177
+ Wordlist::Builder.open('path/to/file.txt.gz') do |builder|
178
+ # ...
179
+ end
180
+ ```
76
181
 
77
- list.mutate 'o', '0'
78
- list.mutate '@', 0x41
79
- list.mutate(/[hax]/i) { |match| match.swapcase }
182
+ Add individual words:
80
183
 
81
- list.each_mutation do |word|
82
- puts word
83
- end
184
+ ```ruby
185
+ builder.add(word)
186
+ ```
84
187
 
85
- ## Requirements
188
+ Adding an Array of words:
86
189
 
87
- * [spidr](http://spidr.rubyforge.org) >= 0.1.9
190
+ ```ruby
191
+ builder.append(words)
192
+ ```
193
+
194
+ Parsing text:
195
+
196
+ ```ruby
197
+ builder.parse(text)
198
+ ```
199
+
200
+ Parsing a file's content:
201
+
202
+ ```ruby
203
+ builder.parse_file(path)
204
+ ```
88
205
 
89
206
  ## Install
90
207
 
91
- $ gem install wordlist
208
+ ```shell
209
+ $ gem install wordlist
210
+ ```
211
+
212
+ ### gemspec
213
+
214
+ ```ruby
215
+ gem.add_dependency 'wordlist', '~> 1.0'
216
+ ```
217
+
218
+ ### Gemfile
219
+
220
+ ```ruby
221
+ gem 'wordlist', '~> 1.0'
222
+ ```
223
+
224
+ ### Synopsis
225
+
226
+ Reading a wordlist:
227
+
228
+ ```shell
229
+ $ wordlist rockyou.txt.gz
230
+ ```
231
+
232
+ Reading multiple wordlists:
233
+
234
+ ```shell
235
+ $ wordlist sport_teams.txt beers.txt
236
+ ```
237
+
238
+ Combining every word from one wordlist with another:
239
+
240
+ ```shell
241
+ $ wordlist sport_teams.txt -p beers.txt -p all_four_digits.txt
242
+ ```
243
+
244
+ Combining every word from one wordlist with itself, N times:
245
+
246
+ ```shell
247
+ $ wordlist shakespeare.txt -P 3
248
+ ```
249
+
250
+ Mutating every word in a wordlist:
251
+
252
+ ```shell
253
+ $ wordlist passwords.txt -m o:0 -m e:3 -m a:@
254
+ ```
255
+
256
+ Executing a command on each word in the wordlist:
257
+
258
+ ```shell
259
+ $ wordlist directories.txt --exec "curl -X POST -F 'user=joe&password={}' -o /dev/null -w '%{http_code} {}' https://$TARGET/login"
260
+ ```
261
+
262
+ Building a wordlist from a directory of `.txt` files:
263
+
264
+ ```shell
265
+ $ wordlist --build wordlist.txt dir/*.txt
266
+ ```
267
+
268
+ Building a wordlist from STDIN:
269
+
270
+ ```shell
271
+ $ cat *.txt | wordlist --build wordlist.txt
272
+ ```
273
+
274
+ ## Benchmarks
275
+
276
+ ```
277
+ user system total real
278
+ Wordlist::Builder#parse_text (size=5.4M) 1.943605 0.003809 1.947414 ( 1.955960)
279
+ Wordlist::File#each (N=1000) 0.000544 0.000000 0.000544 ( 0.000559)
280
+ Wordlist::File#concat (N=1000) 0.001143 0.000000 0.001143 ( 0.001153)
281
+ Wordlist::File#subtract (N=1000) 0.001360 0.000000 0.001360 ( 0.001375)
282
+ Wordlist::File#product (N=1000) 0.536518 0.005959 0.542477 ( 0.545536)
283
+ Wordlist::File#power (N=1000) 0.000015 0.000001 0.000016 ( 0.000014)
284
+ Wordlist::File#intersect (N=1000) 0.001389 0.000000 0.001389 ( 0.001407)
285
+ Wordlist::File#union (N=1000) 0.001310 0.000000 0.001310 ( 0.001317)
286
+ Wordlist::File#uniq (N=1000) 0.000941 0.000000 0.000941 ( 0.000948)
287
+ Wordlist::File#tr (N=1000) 0.000725 0.000000 0.000725 ( 0.000736)
288
+ Wordlist::File#sub (N=1000) 0.000863 0.000000 0.000863 ( 0.000870)
289
+ Wordlist::File#gsub (N=1000) 0.001240 0.000000 0.001240 ( 0.001249)
290
+ Wordlist::File#capittalize (N=1000) 0.000821 0.000000 0.000821 ( 0.000828)
291
+ Wordlist::File#upcase (N=1000) 0.000760 0.000000 0.000760 ( 0.000769)
292
+ Wordlist::File#downcase (N=1000) 0.000544 0.000001 0.000545 ( 0.000545)
293
+ Wordlist::File#mutate (N=1000) 0.004656 0.000000 0.004656 ( 0.004692)
294
+ Wordlist::File#mutate_case (N=1000) 24.178521 0.000000 24.178521 ( 24.294962)
295
+ ```
92
296
 
93
297
  ## License
94
298
 
95
- See {file:LICENSE.txt} for license information.
299
+ Copyright (c) 2009-2021 Hal Brodigan
96
300
 
301
+ See {file:LICENSE.txt} for details.
data/Rakefile CHANGED
@@ -1,35 +1,10 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ require 'rubygems/tasks'
2
+ Gem::Tasks.new
3
3
 
4
- begin
5
- gem 'rubygems-tasks', '~> 0.1'
6
- require 'rubygems/tasks'
7
-
8
- Gem::Tasks.new
9
- rescue LoadError => e
10
- warn e.message
11
- warn "Run `gem install rubygems-tasks` to install 'rubygems/tasks'."
12
- end
13
-
14
- begin
15
- gem 'rspec', '~> 2.4'
16
- require 'rspec/core/rake_task'
17
-
18
- RSpec::Core::RakeTask.new
19
- rescue LoadError => e
20
- task :spec do
21
- abort "Please run `gem install rspec` to install RSpec."
22
- end
23
- end
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+ task :test => :spec
24
7
  task :default => :spec
25
8
 
26
- begin
27
- gem 'yard', '~> 0.8'
28
- require 'yard'
29
-
30
- YARD::Rake::YardocTask.new
31
- rescue LoadError => e
32
- task :yard do
33
- abort "Please run `gem install yard` to install YARD."
34
- end
35
- end
9
+ require 'yard'
10
+ YARD::Rake::YardocTask.new
data/benchmarks.rb ADDED
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path(File.join(__dir__,'lib')))
4
+ require 'wordlist'
5
+ require 'fileutils'
6
+ require 'benchmark'
7
+
8
+ DIR = File.join(__dir__,'benchmarks')
9
+ TEXT_FILE = File.join(DIR,'shaks12.txt')
10
+ WORDLIST1 = File.join(DIR,'wordlist1.txt')
11
+ WORDLIST2 = File.join(DIR,'wordlist2.txt')
12
+ N = 1_000
13
+
14
+ FileUtils.mkdir_p(DIR)
15
+
16
+ unless File.file?(TEXT_FILE)
17
+ require 'net/https'
18
+
19
+ uri = URI('https://www.gutenberg.org/files/100/old/shaks12.txt')
20
+
21
+ Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
22
+ request = Net::HTTP::Get.new(uri)
23
+
24
+ http.request(request) do |response|
25
+ File.open(TEXT_FILE,'w') do |file|
26
+ response.read_body do |chunk|
27
+ file.write(chunk)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ unless File.file?(WORDLIST1)
35
+ system("head -n #{N} /usr/share/dict/words > #{WORDLIST1}")
36
+ end
37
+
38
+ unless File.file?(WORDLIST2)
39
+ system("tail -n #{N} /usr/share/dict/words > #{WORDLIST2}")
40
+ end
41
+
42
+ Benchmark.bm(40) do |b|
43
+ b.report("Wordlist::Builder#parse_text (size=5.4M)") do
44
+ Wordlist::Builder.open(File.join(DIR,'shakespeare.txt')) do |builder|
45
+ builder.parse_file(TEXT_FILE)
46
+ end
47
+ end
48
+
49
+ b.report("Wordlist::File#each (N=#{N})") do
50
+ Wordlist::File.open(WORDLIST1).each { |word| }
51
+ end
52
+
53
+ wordlist1 = Wordlist::File.open(WORDLIST1)
54
+ wordlist2 = Wordlist::File.open(WORDLIST2)
55
+
56
+ b.report("Wordlist::File#concat (N=#{N})") do
57
+ wordlist1.concat(wordlist2).each { |word| }
58
+ end
59
+
60
+ b.report("Wordlist::File#subtract (N=#{N})") do
61
+ wordlist1.subtract(wordlist2).each { |word| }
62
+ end
63
+
64
+ b.report("Wordlist::File#product (N=#{N})") do
65
+ wordlist1.product(wordlist2).each { |word| }
66
+ end
67
+
68
+ b.report("Wordlist::File#power (N=#{N})") do
69
+ wordlist1.power(2)
70
+ end
71
+
72
+ b.report("Wordlist::File#intersect (N=#{N})") do
73
+ wordlist1.intersect(wordlist2).each { |word| }
74
+ end
75
+
76
+ b.report("Wordlist::File#union (N=#{N})") do
77
+ wordlist1.union(wordlist2).each { |word| }
78
+ end
79
+
80
+ b.report("Wordlist::File#uniq (N=#{N})") do
81
+ wordlist1.uniq.each { |word| }
82
+ end
83
+
84
+ b.report("Wordlist::File#tr (N=#{N})") do
85
+ wordlist1.tr("e","3").each { |word| }
86
+ end
87
+
88
+ b.report("Wordlist::File#sub (N=#{N})") do
89
+ wordlist1.sub("e","3").each { |word| }
90
+ end
91
+
92
+ b.report("Wordlist::File#gsub (N=#{N})") do
93
+ wordlist1.gsub("e","3").each { |word| }
94
+ end
95
+
96
+ b.report("Wordlist::File#capittalize (N=#{N})") do
97
+ wordlist1.capitalize.each { |word| }
98
+ end
99
+
100
+ b.report("Wordlist::File#upcase (N=#{N})") do
101
+ wordlist1.upcase.each { |word| }
102
+ end
103
+
104
+ b.report("Wordlist::File#downcase (N=#{N})") do
105
+ wordlist1.downcase.each { |word| }
106
+ end
107
+
108
+ b.report("Wordlist::File#mutate (N=#{N})") do
109
+ wordlist1.mutate("e","3").each { |word| }
110
+ end
111
+
112
+ b.report("Wordlist::File#mutate_case (N=#{N})") do
113
+ wordlist1.mutate_case.each { |word| }
114
+ end
115
+ end
data/bin/wordlist CHANGED
@@ -1,10 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib_dir = File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
4
- unless $LOAD_PATH.include?(lib_dir)
5
- $LOAD_PATH << lib_dir
6
- end
3
+ lib_dir = File.expand_path(File.join(__dir__,'..','lib'))
4
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
7
5
 
8
- require 'wordlist/runners/list'
9
-
10
- Wordlist::Runners::List.run(*ARGV)
6
+ require 'wordlist/cli'
7
+ exit Wordlist::CLI.run(ARGV)