wordlist 0.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)