wordlist 0.1.1 → 1.0.1

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 (152) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +6 -3
  4. data/ChangeLog.md +55 -1
  5. data/Gemfile +15 -0
  6. data/LICENSE.txt +1 -3
  7. data/README.md +301 -60
  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 +13 -12
  54. data/lib/wordlist/abstract_wordlist.rb +25 -0
  55. data/lib/wordlist/builder.rb +172 -138
  56. data/lib/wordlist/cli.rb +459 -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 +177 -0
  61. data/lib/wordlist/format.rb +39 -0
  62. data/lib/wordlist/lexer/lang.rb +34 -0
  63. data/lib/wordlist/lexer/stop_words.rb +69 -0
  64. data/lib/wordlist/lexer.rb +221 -0
  65. data/lib/wordlist/list_methods.rb +462 -0
  66. data/lib/wordlist/modifiers/capitalize.rb +46 -0
  67. data/lib/wordlist/modifiers/downcase.rb +46 -0
  68. data/lib/wordlist/modifiers/gsub.rb +52 -0
  69. data/lib/wordlist/modifiers/modifier.rb +44 -0
  70. data/lib/wordlist/modifiers/mutate.rb +134 -0
  71. data/lib/wordlist/modifiers/mutate_case.rb +26 -0
  72. data/lib/wordlist/modifiers/sub.rb +98 -0
  73. data/lib/wordlist/modifiers/tr.rb +72 -0
  74. data/lib/wordlist/modifiers/upcase.rb +46 -0
  75. data/lib/wordlist/modifiers.rb +9 -0
  76. data/lib/wordlist/operators/binary_operator.rb +39 -0
  77. data/lib/wordlist/operators/concat.rb +48 -0
  78. data/lib/wordlist/operators/intersect.rb +56 -0
  79. data/lib/wordlist/operators/operator.rb +29 -0
  80. data/lib/wordlist/operators/power.rb +73 -0
  81. data/lib/wordlist/operators/product.rb +51 -0
  82. data/lib/wordlist/operators/subtract.rb +55 -0
  83. data/lib/wordlist/operators/unary_operator.rb +30 -0
  84. data/lib/wordlist/operators/union.rb +62 -0
  85. data/lib/wordlist/operators/unique.rb +53 -0
  86. data/lib/wordlist/operators.rb +8 -0
  87. data/lib/wordlist/unique_filter.rb +41 -61
  88. data/lib/wordlist/version.rb +4 -2
  89. data/lib/wordlist/words.rb +72 -0
  90. data/lib/wordlist.rb +104 -2
  91. data/spec/abstract_list_spec.rb +18 -0
  92. data/spec/builder_spec.rb +220 -76
  93. data/spec/cli_spec.rb +802 -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 +269 -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 +718 -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/unary_operator_spec.rb +14 -0
  128. data/spec/operators/union_spec.rb +37 -0
  129. data/spec/operators/unique_spec.rb +25 -0
  130. data/spec/spec_helper.rb +2 -1
  131. data/spec/unique_filter_spec.rb +108 -18
  132. data/spec/wordlist_spec.rb +55 -3
  133. data/spec/words_spec.rb +41 -0
  134. data/wordlist.gemspec +1 -0
  135. metadata +164 -126
  136. data/lib/wordlist/builders/website.rb +0 -216
  137. data/lib/wordlist/builders.rb +0 -1
  138. data/lib/wordlist/flat_file.rb +0 -47
  139. data/lib/wordlist/list.rb +0 -162
  140. data/lib/wordlist/mutator.rb +0 -113
  141. data/lib/wordlist/parsers.rb +0 -74
  142. data/lib/wordlist/runners/list.rb +0 -116
  143. data/lib/wordlist/runners/runner.rb +0 -67
  144. data/lib/wordlist/runners.rb +0 -2
  145. data/scripts/benchmark +0 -59
  146. data/scripts/text/comedy_of_errors.txt +0 -4011
  147. data/spec/classes/parser_class.rb +0 -7
  148. data/spec/classes/test_list.rb +0 -9
  149. data/spec/flat_file_spec.rb +0 -25
  150. data/spec/list_spec.rb +0 -58
  151. data/spec/mutator_spec.rb +0 -43
  152. data/spec/parsers_spec.rb +0 -118
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3648b45622323ff7c7c9a39d3cdb458d40388f1f0840fb80b917239df7ae995a
4
+ data.tar.gz: 8302f069d5a7dfd68103cfa106df8ade1b1d00f7f6755be7158dd7acd2a4bf0e
5
+ SHA512:
6
+ metadata.gz: 01662d4d752294cca6da0809f7dfc0a953f7702259c448d73b4cfc796d214ce90797e4eedc80ebd48d005ec67039124ab5e974add35fadc8552f5cc9e6683de1
7
+ data.tar.gz: d29b36e5319a75bd9d88617451e6a7fda6c0cf4d0fe4cb43fd41b19da1e960135a57982b09f3ce93ff106668443ba03f26479a664c73737cc7721d8e2d0f26e5
@@ -0,0 +1,28 @@
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
+ - 3.1
16
+ - jruby
17
+ - truffleruby
18
+ name: Ruby ${{ matrix.ruby }}
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby }}
25
+ - name: Install dependencies
26
+ run: bundle install --jobs 4 --retry 3
27
+ - name: Run tests
28
+ 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,60 @@
1
+ ### 1.0.1 / 2023-07-17
2
+
3
+ * Require Ruby >= 2.0.0.
4
+ * Added `frozen_string_literal: true` magic comments.
5
+ * Flush the output after each line is written in {Wordlist::Builder}.
6
+ This allows for watching the wordlist file grow using `tail -f`.
7
+ * Fixed a bug in {Wordlist::Lexer#parse} where Unicode whitespace or other
8
+ Unicode characters caused an infinite loop.
9
+ * Various documentation fixes.
10
+
11
+ ### 1.0.0 / 2021-11-01
12
+
13
+ * Redesigned the API.
14
+ * Added {Wordlist::AbstractWordlist}.
15
+ * Added {Wordlist::ListMethods}.
16
+ * Added {Wordlist::Operators}.
17
+ * Added {Wordlist::Operators::Operator}.
18
+ * Added {Wordlist::Operators::UnaryOperator}.
19
+ * Added {Wordlist::Operators::BinaryOperator}.
20
+ * Added {Wordlist::Operators::Concat}.
21
+ * Added {Wordlist::Operators::Subtract}.
22
+ * Added {Wordlist::Operators::Product}.
23
+ * Added {Wordlist::Operators::Power}.
24
+ * Added {Wordlist::Operators::Union}.
25
+ * Added {Wordlist::Operators::Intersect}.
26
+ * Added {Wordlist::Operators::Unique}.
27
+ * Added {Wordlist::Modifiers}.
28
+ * Added {Wordlist::Modifiers::Modifier}.
29
+ * Added {Wordlist::Modifiers::Capitalize}.
30
+ * Added {Wordlist::Modifiers::Downcase}.
31
+ * Added {Wordlist::Modifiers::Upcase}.
32
+ * Added {Wordlist::Modifiers::Tr}.
33
+ * Added {Wordlist::Modifiers::Sub}.
34
+ * Added {Wordlist::Modifiers::Gsub}.
35
+ * Added {Wordlist::Modifiers::Mutate}.
36
+ * Added {Wordlist::Modifiers::MutateCase}.
37
+ * Added {Wordlist::Words}.
38
+ * Added {Wordlist::Format}.
39
+ * Added {Wordlist::Compression}.
40
+ * Added {Wordlist::Compression::Reader}.
41
+ * Added {Wordlist::Compression::Writer}.
42
+ * Added {Wordlist::File}.
43
+ * Added {Wordlist::Lexer}.
44
+ * Added {Wordlist::Lexer::StopWords}.
45
+ * Added {Wordlist::Builder}.
46
+ * Added {Wordlist::CLI}.
47
+ * Refactored {Wordlist::UniqueFilter} to only store Object hashes.
48
+ * Removed `Wordlist::List`.
49
+ * Removed `Wordlist::FlatFile`.
50
+ * Removed `Wordlist::Mutator` in favor of {Wordlist::Modifiers::Mutate}.
51
+ * Removed `Wordlist::Parsers` in favor of {Wordlist::Lexer}.
52
+ * Removed `Wordlist::Builders`.
53
+ * Removed `Wordlist::Runners`.
54
+
1
55
  ### 0.1.1 / 2012-06-11
2
56
 
3
- * Default {Wordlist::Builders::Website#proxy} to `Spidr.proxy`.
57
+ * Default `Wordlist::Builders::Website#proxy` to `Spidr.proxy`.
4
58
 
5
59
  ### 0.1.0 / 2009-08-31
6
60
 
data/Gemfile ADDED
@@ -0,0 +1,15 @@
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
+
11
+ gem 'kramdown'
12
+ gem 'redcarpet', platform: :mri
13
+ gem 'yard', '~> 0.9'
14
+ gem 'yard-spellcheck', require: false
15
+ 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,337 @@
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
+ [![Code Climate](https://codeclimate.com/github/postmodern/wordlist.rb.svg)](https://codeclimate.com/github/postmodern/wordlist.rb)
5
+ [![Gem Version](https://badge.fury.io/rb/wordlist.svg)](https://badge.fury.io/rb/wordlist)
6
+
7
+ * [Source](https://github.com/postmodern/wordlist.rb#readme)
8
+ * [Issues](https://github.com/postmodern/wordlist.rb/issues)
9
+ * [Documentation](https://rubydoc.info/gems/wordlist/frames)
6
10
 
7
11
  ## Description
8
12
 
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.
13
+ Wordlist is a Ruby library and CLI for reading, combining, mutating, and
14
+ building wordlists, efficiently.
14
15
 
15
16
  ## Features
16
17
 
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.
18
+ * Supports reading `.txt` wordlists, and `.txt.gz`, `.txt.bz2`, and `.txt.xz`
19
+ compressed wordlists.
20
+ * Supports building wordlists from arbitrary text. Also supports `.gz`, `.bz2,`
21
+ and `.xz` compression.
22
+ * Provides an advanced lexer for parsing text into words.
23
+ * Can parse/skip digits, special characters, whole numbers, acronyms.
24
+ * Can normalize case, apostrophes, and acronyms.
25
+ * Supports wordlist operations for combining multiple wordlists together.
26
+ * Supports wordlist modify or mutating the words in the wordlist on the fly.
27
+ * Also provides a `wordlist` [command](#synopsis).
28
+ * [Fast-ish](#benchmarks)
30
29
 
31
30
  ## Examples
32
31
 
33
- Build a word-list from arbitrary text:
32
+ ### Reading
33
+
34
+ Open a wordlist for reading:
35
+
36
+ ```ruby
37
+ wordlist = Wordlist.open("passwords.txt")
38
+ ```
39
+
40
+ Open a compressed wordlist for reading:
41
+
42
+ ```ruby
43
+ wordlist = Wordlist.open("rockyou.txt.gz")
44
+ ```
45
+
46
+ Enumerate through a wordlist:
47
+
48
+ ```ruby
49
+ wordlist.each do |word|
50
+ puts word
51
+ end
52
+ ```
53
+
54
+ Create an in-memory list of literal words:
55
+
56
+ ```ruby
57
+ words = Wordlist::Words["foo", "bar", "baz"]
58
+ ```
59
+
60
+ ### List Operations
61
+
62
+ Concat two wordlists together:
63
+
64
+ ```ruby
65
+ (wordlist1 + wordlist2).each do |word|
66
+ puts word
67
+ end
68
+ ```
69
+
70
+ Union two wordlists together:
71
+
72
+ ```ruby
73
+ (wordlist1 | wordlist2).each do |word|
74
+ puts word
75
+ end
76
+ ```
77
+
78
+ Subtract one wordlist from the other:
79
+
80
+ ```ruby
81
+ (wordlist1 - wordlist2).each do |word|
82
+ puts word
83
+ end
84
+ ```
85
+
86
+ Combine every word from `wordlist1` with the words from `wordlist2`:
87
+
88
+ ```ruby
89
+ (wordlist1 * wordlist2).each do |word|
90
+ puts word
91
+ end
92
+ ```
93
+
94
+ Combine the wordlist with itself multiple times:
95
+
96
+ ```ruby
97
+ (wordslist ** 3).each do |word|
98
+ puts word
99
+ end
100
+ ```
101
+
102
+ Filter out duplicates from multiple wordlists:
103
+
104
+ ```ruby
105
+ (wordlist1 + wordlist2 + wordlist3).uniq.each do |word|
106
+ puts word
107
+ end
108
+ ```
109
+
110
+ ### String Manipulation
111
+
112
+ Convert every word in a wordlist to lowercase:
113
+
114
+ ```ruby
115
+ wordlist.downcase.each do |word|
116
+ puts word
117
+ end
118
+ ```
119
+
120
+ Convert every word in a wordlist to UPPERCASE:
121
+
122
+ ```ruby
123
+ wordlist.upcase.each do |word|
124
+ puts word
125
+ end
126
+ ```
127
+
128
+ Capitalize every word in a wordlist:
129
+
130
+ ```ruby
131
+ wordlist.capitalize.each do |word|
132
+ puts word
133
+ end
134
+ ```
34
135
 
35
- Wordlist::Builder.build('list.txt') do |builder|
36
- builder.parse(some_text)
37
- end
136
+ Run `String#tr` on every word in a wordlist:
38
137
 
39
- Build a word-list from another file:
138
+ ```ruby
139
+ wordlist.tr('_','-').each do |word|
140
+ puts word
141
+ end
142
+ ```
40
143
 
41
- Wordlist::Builder.build('list.txt') do |builder|
42
- builder.parse_file('some/file.txt')
43
- end
144
+ Run `String#sub` on every word in a wordlist:
44
145
 
45
- Build a word-list of phrases containing at most three words, from the
46
- arbitrary text:
146
+ ```ruby
147
+ wordlist.sub("fish","phish").each do |word|
148
+ puts word
149
+ end
150
+ ```
47
151
 
48
- Wordlist::Builder.build('list.txt', :max_words => 3) do |builder|
49
- builder.parse(some_text)
50
- end
152
+ Run `String#gsub` on every word in a wordlist:
51
153
 
52
- Build a word-list from content off a website:
154
+ ```ruby
155
+ wordlist.gsub(/\d+/,"").each do |word|
156
+ puts word
157
+ end
158
+ ```
53
159
 
54
- require 'wordlist/builders/website'
160
+ Performs every possible mutation of each word in a wordlist:
55
161
 
56
- Wordlist::Builders::Website.build(
57
- 'list.txt',
58
- :host => 'www.example.com'
59
- )
162
+ ```ruby
163
+ wordlist.mutate(/[oae]/, {'o' => '0', 'a' => '@', 'e' => '3'}).each do |word|
164
+ puts word
165
+ end
166
+ # dog
167
+ # d0g
168
+ # firefox
169
+ # fir3fox
170
+ # firef0x
171
+ # fir3f0x
172
+ # ...
173
+ ```
60
174
 
61
- Enumerate through each word in a flat-file word-list:
175
+ Enumerates over every possible case variation of every word in a wordlist:
62
176
 
63
- list = Wordlist::FlatFile.new('list.txt')
64
- list.each_word do |word|
65
- puts word
66
- end
177
+ ```ruby
178
+ wordlist.mutate_case.each do |word|
179
+ puts word
180
+ end
181
+ # cat
182
+ # Cat
183
+ # cAt
184
+ # caT
185
+ # CAt
186
+ # CaT
187
+ # cAT
188
+ # CAT
189
+ # ...
190
+ ```
67
191
 
68
- Enumerate through each unique word in a flat-file word-list:
192
+ ### Building a Wordlist
69
193
 
70
- list.each_unique do |word|
71
- puts word
72
- end
194
+ ```ruby
195
+ Wordlist::Builder.open('path/to/file.txt.gz') do |builder|
196
+ # ...
197
+ end
198
+ ```
73
199
 
74
- Define mutation rules, and enumerate through each unique mutation of each
75
- unique word in the word-list:
200
+ Add individual words:
76
201
 
77
- list.mutate 'o', '0'
78
- list.mutate '@', 0x41
79
- list.mutate(/[hax]/i) { |match| match.swapcase }
202
+ ```ruby
203
+ builder.add(word)
204
+ ```
80
205
 
81
- list.each_mutation do |word|
82
- puts word
83
- end
206
+ Adding an Array of words:
207
+
208
+ ```ruby
209
+ builder.append(words)
210
+ ```
211
+
212
+ Parsing text:
213
+
214
+ ```ruby
215
+ builder.parse(text)
216
+ ```
217
+
218
+ Parsing a file's content:
219
+
220
+ ```ruby
221
+ builder.parse_file(path)
222
+ ```
84
223
 
85
224
  ## Requirements
86
225
 
87
- * [spidr](http://spidr.rubyforge.org) >= 0.1.9
226
+ * [ruby] >= 2.0.0
227
+
228
+ [ruby]: https://www.ruby-lang.org/
88
229
 
89
230
  ## Install
90
231
 
91
- $ gem install wordlist
232
+ ```shell
233
+ $ gem install wordlist
234
+ ```
235
+
236
+ ### gemspec
237
+
238
+ ```ruby
239
+ gem.add_dependency 'wordlist', '~> 1.0'
240
+ ```
241
+
242
+ ### Gemfile
243
+
244
+ ```ruby
245
+ gem 'wordlist', '~> 1.0'
246
+ ```
247
+
248
+ ### Synopsis
249
+
250
+ Reading a wordlist:
251
+
252
+ ```shell
253
+ $ wordlist rockyou.txt.gz
254
+ ```
255
+
256
+ Reading multiple wordlists:
257
+
258
+ ```shell
259
+ $ wordlist sport_teams.txt beers.txt
260
+ ```
261
+
262
+ Combining every word from one wordlist with another:
263
+
264
+ ```shell
265
+ $ wordlist sport_teams.txt -p beers.txt -p all_four_digits.txt
266
+ coors0000
267
+ coors0001
268
+ coors0002
269
+ coors0003
270
+ ...
271
+ ```
272
+
273
+ Combining every word from one wordlist with itself, N times:
274
+
275
+ ```shell
276
+ $ wordlist words.txt -P 3
277
+ ```
278
+
279
+ Mutating every word in a wordlist:
280
+
281
+ ```shell
282
+ $ wordlist passwords.txt -m o:0 -m e:3 -m a:@
283
+ dog
284
+ d0g
285
+ firefox
286
+ fir3fox
287
+ firef0x
288
+ fir3f0x
289
+ ...
290
+ ```
291
+
292
+ Executing a command on each word in the wordlist:
293
+
294
+ ```shell
295
+ $ wordlist directories.txt --exec "curl -X POST -F 'user=joe&password={}' -o /dev/null -w '%{http_code} {}' https://$TARGET/login"
296
+ ```
297
+
298
+ Building a wordlist from a directory of `.txt` files:
299
+
300
+ ```shell
301
+ $ wordlist --build wordlist.txt dir/*.txt
302
+ ```
303
+
304
+ Building a wordlist from STDIN:
305
+
306
+ ```shell
307
+ $ cat *.txt | wordlist --build wordlist.txt
308
+ ```
309
+
310
+ ## Benchmarks
311
+
312
+ ```
313
+ user system total real
314
+ Wordlist::Builder#parse_text (size=5.4M) 1.943605 0.003809 1.947414 ( 1.955960)
315
+ Wordlist::File#each (N=1000) 0.000544 0.000000 0.000544 ( 0.000559)
316
+ Wordlist::File#concat (N=1000) 0.001143 0.000000 0.001143 ( 0.001153)
317
+ Wordlist::File#subtract (N=1000) 0.001360 0.000000 0.001360 ( 0.001375)
318
+ Wordlist::File#product (N=1000) 0.536518 0.005959 0.542477 ( 0.545536)
319
+ Wordlist::File#power (N=1000) 0.000015 0.000001 0.000016 ( 0.000014)
320
+ Wordlist::File#intersect (N=1000) 0.001389 0.000000 0.001389 ( 0.001407)
321
+ Wordlist::File#union (N=1000) 0.001310 0.000000 0.001310 ( 0.001317)
322
+ Wordlist::File#uniq (N=1000) 0.000941 0.000000 0.000941 ( 0.000948)
323
+ Wordlist::File#tr (N=1000) 0.000725 0.000000 0.000725 ( 0.000736)
324
+ Wordlist::File#sub (N=1000) 0.000863 0.000000 0.000863 ( 0.000870)
325
+ Wordlist::File#gsub (N=1000) 0.001240 0.000000 0.001240 ( 0.001249)
326
+ Wordlist::File#capittalize (N=1000) 0.000821 0.000000 0.000821 ( 0.000828)
327
+ Wordlist::File#upcase (N=1000) 0.000760 0.000000 0.000760 ( 0.000769)
328
+ Wordlist::File#downcase (N=1000) 0.000544 0.000001 0.000545 ( 0.000545)
329
+ Wordlist::File#mutate (N=1000) 0.004656 0.000000 0.004656 ( 0.004692)
330
+ Wordlist::File#mutate_case (N=1000) 24.178521 0.000000 24.178521 ( 24.294962)
331
+ ```
92
332
 
93
333
  ## License
94
334
 
95
- See {file:LICENSE.txt} for license information.
335
+ Copyright (c) 2009-2021 Hal Brodigan
96
336
 
337
+ 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