Module: Pwnlib::Util::Cyclic
- Included in:
- Pwn
- Defined in:
- lib/pwnlib/util/cyclic.rb
Overview
Generate string with easy-to-find pattern.
Class Method Summary collapse
-
.cyclic(length = nil, alphabet: ASCII_LOWERCASE, n: 4) ⇒ String, Array
Simple wrapper over Cyclic.de_bruijn, returning at most
lengthitems. -
.cyclic_find(subseq, alphabet: ASCII_LOWERCASE, n: nil) ⇒ Integer?
Find the position of a substring in a De Bruijn sequence.
-
.de_bruijn(alphabet: ASCII_LOWERCASE, n: 4) ⇒ Object
Generator for a sequence of unique substrings of length
n.
Class Method Details
.cyclic(length = nil, alphabet: ASCII_LOWERCASE, n: 4) ⇒ String, Array
Simple wrapper over de_bruijn, returning at most length items.
81 82 83 84 85 |
# File 'lib/pwnlib/util/cyclic.rb', line 81 def cyclic(length = nil, alphabet: ASCII_LOWERCASE, n: 4) enum = de_bruijn(alphabet: alphabet, n: n) r = length.nil? ? enum.to_a : enum.take(length) alphabet.is_a?(String) ? r.join : r end |
.cyclic_find(subseq, alphabet: ASCII_LOWERCASE, n: nil) ⇒ Integer?
TODO:
Speed! See comment in Python pwntools.
Find the position of a substring in a De Bruijn sequence.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/pwnlib/util/cyclic.rb', line 104 def cyclic_find(subseq, alphabet: ASCII_LOWERCASE, n: nil) n ||= subseq.size subseq = subseq.chars if subseq.is_a?(String) return nil unless subseq.all? { |c| alphabet.include?(c) } pos = 0 saved = [] de_bruijn(alphabet: alphabet, n: n).each do |c| saved << c if saved.size > subseq.size saved.shift pos += 1 end return pos if saved == subseq end nil end |
.de_bruijn(alphabet: ASCII_LOWERCASE, n: 4) {|c| ... } ⇒ void .de_bruijn(alphabet: ASCII_LOWERCASE, n: 4) ⇒ Enumerator
Generator for a sequence of unique substrings of length n. This is implemented using a De Bruijn Sequence over the given alphabet. Returns an Enumerator if no block given.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/pwnlib/util/cyclic.rb', line 44 def de_bruijn(alphabet: ASCII_LOWERCASE, n: 4) return to_enum(__method__, alphabet: alphabet, n: n) { alphabet.size**n } unless block_given? k = alphabet.size a = [0] * (k * n) db = lambda do |t, p| if t > n (1..p).each { |j| yield alphabet[a[j]] } if (n % p).zero? else a[t] = a[t - p] db.call(t + 1, p) (a[t - p] + 1...k).each do |j| a[t] = j db.call(t + 1, t) end end end db[1, 1] end |