Class: String

Inherits:
Object show all
Defined in:
lib/ronin/extensions/string.rb,
lib/ronin/formatting/extensions/sql/string.rb,
lib/ronin/formatting/extensions/html/string.rb,
lib/ronin/formatting/extensions/http/string.rb,
lib/ronin/formatting/extensions/text/string.rb,
lib/ronin/formatting/extensions/binary/string.rb,
lib/ronin/formatting/extensions/digest/string.rb

Overview

Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)

This file is part of Ronin Support.

Ronin Support is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Ronin Support is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with Ronin Support. If not, see http://www.gnu.org/licenses/.

Constant Summary collapse

ESCAPE_BYTES =
Hash.new do |escape,byte|
  escape[byte] = if (byte >= 0x20 && byte <= 0x7e)
                   byte.chr
                 else
                   "\\x%.2X" % byte
                 end
end
JS_BACKSLASHED_CHARS =

JavaScript characters that must be back-slashed.

{
  "\\b" => "\b",
  "\\t" => "\t",
  "\\n" => "\n",
  "\\f" => "\f",
  "\\r" => "\r",
  "\\\"" => "\"",
  "\\\\" => "\\"
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.generate(*template) {|string| ... } ⇒ Enumerator

Generate permutations of Strings from a format template.

Examples:

Generate Strings with ranges of repeating sub-strings.

Generate Strings with three alpha chars and one numeric chars.

String.generate([:alpha, 3], :numeric) do |password|
  puts password
end

Generate Strings with two to four alpha chars.

String.generate([:alpha, 2..4]) do |password|
  puts password
end

Generate Strings using alpha and punctuation chars.

String.generate([Chars.alpha + Chars.punctuation, 4]) do |password|
  puts password
end

Generate Strings from a custom char set.

String.generate([['a', 'b', 'c'], 3], [['1', '2', '3'], 3]) do |password|
  puts password
end

Generate Strings containing known Strings.

String.generate("rock", [:numeric, 4]) do |password|
  puts password
end

Generate Strings with ranges of repeating sub-strings.

String.generate(['/AA', (1..100).step(5)]) do |path|
  puts path
end

Parameters:

Yields:

  • (string)

    The given block will be passed each unique String.

Yield Parameters:

  • string (String)

    A newly generated String.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.

Raises:

  • (ArgumentError)

    A given character set name was unknown.

  • (TypeError)

    A given string set was not a String, Symbol or Enumerable. A given string set length was not an Integer or Enumerable.

Since:

  • 0.3.0


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ronin/formatting/extensions/text/string.rb', line 86

def self.generate(*template)
  return enum_for(:generate,*template) unless block_given?

  sets = []

  template.each do |pattern|
    set, length = pattern
    set = case set
          when String
            [set].each
          when Symbol
            name = set.to_s.upcase

            unless Chars.const_defined?(name)
              raise(ArgumentError,"unknown charset #{set.inspect}")
            end

            Chars.const_get(name).each_char
          when Enumerable
            Chars::CharSet.new(set).each_char
          else
            raise(TypeError,"set must be a String, Symbol or Enumerable")
          end

    case length
    when Integer
      length.times { sets << set.dup }
    when Enumerable
      sets << Combinatorics::Generator.new do |g|
        length.each do |sublength|
          superset = Array.new(sublength) { set.dup }

          superset.comprehension { |strings| g.yield strings.join }
        end
      end
    when nil
      sets << set
    else
      raise(TypeError,"length must be an Integer or Enumerable")
    end
  end

  sets.comprehension { |strings| yield strings.join }
  return nil
end

Instance Method Details

#base64_decodeString

Base64 decodes a string.

Examples:

"aGVsbG8=\n"
# => "hello"

Returns:

  • (String)

    The base64 decoded form of the string.


260
261
262
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 260

def base64_decode
  Base64.decode64(self)
end

#base64_encodeString

Base64 encodes a string.

Examples:

"hello".base64_encode
# => "aGVsbG8=\n"

Returns:

  • (String)

    The base64 encoded form of the string.


244
245
246
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 244

def base64_encode
  Base64.encode64(self)
end

#common_postfix(other) ⇒ Object

Deprecated.

Deprecates as of 0.2.0, and will be removed in 1.0.0. Please use #common_suffix instead.


170
171
172
173
174
175
# File 'lib/ronin/extensions/string.rb', line 170

def common_postfix(other)
  warn 'DEPRECATED: String#common_postfix was deprecated in 0.2.0.'
  warn 'DEPRECATED: Please use String#common_suffix instead.'

  common_suffix(other)
end

#common_prefix(other) ⇒ String

The common prefix of the string and the specified other string.

Parameters:

  • other (String)

    The other String to compare against.

Returns:

  • (String)

    The common prefix between the two Strings.


125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ronin/extensions/string.rb', line 125

def common_prefix(other)
  min_length = [length, other.length].min

  min_length.times do |i|
    if self[i] != other[i]
      return self[0,i]
    end
  end

  return self[0,min_length]
end

#common_suffix(other) ⇒ String

Finds the common suffix of the string and the specified other string.

Parameters:

  • pther (String)

    The other String to compare against.

Returns:

  • (String)

    The common suffix of the two Strings.

Since:

  • 0.2.0


150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/ronin/extensions/string.rb', line 150

def common_suffix(other)
  min_length = [length, other.length].min

  (min_length - 1).times do |i|
    index       = (length - i - 1)
    other_index = (other.length - i - 1)

    if self[index] != other[other_index]
      return self[(index + 1)..-1]
    end
  end

  return ''
end

#depack(arch, address_length = nil) ⇒ Integer

Packs an Integer from a String, which was originally packed for a specific architecture and address-length.

Examples:

using archs other than Ronin::Arch.

arch = OpenStruct.new(:endian => :little, :address_length => 4)

"A\0\0\0".depack(arch)
# => 65

using a Ronin::Arch arch.

"A\0\0\0".depack(Arch.i386)
# => 65

specifying a custom address-length.

"A\0".depack(Arch.ppc,2)
# => 65

using a String#unpack template String as the arch.

"A\0\0\0".depack('L')
# => 65

Parameters:

  • arch (Ronin::Arch, #endian, #address_length, String)

    The architecture that the Integer was originally packed with.

  • address_length (Integer) (defaults to: nil)

    The number of bytes to depack.

Returns:

  • (Integer)

    The depacked Integer.

Raises:

  • (ArgumentError)

    The given arch does not respond to the endian or address_length methods.

See Also:


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 74

def depack(arch,address_length=nil)
  if arch.kind_of?(String)
    return self.unpack(arch)
  end

  unless arch.respond_to?(:address_length)
    raise(ArgumentError,"first argument to Ineger#pack must respond to address_length")
  end

  unless arch.respond_to?(:endian)
    raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
  end

  endian           = arch.endian.to_sym
  address_length ||= arch.address_length

  integer = 0x0
  byte_index = 0

  case endian
  when :little
    mask = lambda { |b| b << (byte_index * 8) }
  when :big
    mask = lambda { |b|
      b << ((address_length - byte_index - 1) * 8)
    }
  else
    raise(ArgumentError,"invalid endian #{arch.endian.inspect}")
  end

  each_byte do |b|
    break if byte_index >= address_length

    integer |= mask.call(b)
    byte_index += 1
  end

  return integer
end

#dumpString Also known as: inspect

Note:

This method is only defined on Ruby 1.8.x.

Dumps the string as a C-style string.

Examples:

"hello\x00\073\x90\r\n".dump
# => "hello\0;\x90\r\n"

Returns:

  • (String)

    The C-style encoded version of the String.


229
230
231
232
233
234
# File 'lib/ronin/extensions/string.rb', line 229

def dump
  dumped_string = ''

  each_byte { |b| dumped_string << ESCAPE_BYTES[b] }
  return "\"#{dumped_string}\""
end

#each_substring(min = 1) {|substring, (index)| ... } ⇒ String

Enumerates over every sub-string within the string.

Examples:

"hello".each_substring(3).to_a
# => ["hel", "hell", "hello", "ell", "ello", "llo"]

Parameters:

  • min (Integer) (defaults to: 1)

    Minimum length of each sub-string.

Yields:

  • (substring, (index))

    The given block will receive every sub-string contained within the string. If the block accepts two arguments, then the index of the sub-string will also be passed in.

Yield Parameters:

  • substring (String)

    A sub-string from the string.

  • index (Integer)

    The optional index of the sub-string.

Returns:

  • (String)

    The original string


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ronin/extensions/string.rb', line 48

def each_substring(min=1,&block)
  return enum_for(:each_substring,min) unless block

  (0..(length - min)).each do |i|
    ((i + min)..length).each do |j|
      sub_string = self[i...j]

      if block.arity == 2
        block.call(sub_string,i)
      else
        block.call(sub_string)
      end
    end
  end

  return self
end

#each_unique_substring(min = 1) {|substring, (index)| ... } ⇒ String

Enumerates over the unique sub-strings contained in the string.

Examples:

"xoxo".each_unique_substring(2).to_a
# => ["xo", "xox", "xoxo", "ox", "oxo"]

Parameters:

  • min (Integer) (defaults to: 1)

    Minimum length of each unique sub-string.

Yields:

  • (substring, (index))

    The given block will receive every unique sub-string contained within the string. If the block accepts two arguments, then the index of the unique sub-string will also be passed in.

Yield Parameters:

  • substring (String)

    A unique sub-string from the string.

  • index (Integer)

    The optional index of the unique sub-string.

Returns:

  • (String)

    The original string

See Also:


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ronin/extensions/string.rb', line 94

def each_unique_substring(min=1,&block)
  return enum_for(:each_unique_substring,min) unless block

  unique_strings = {}

  each_substring(min) do |sub_string,index|
    unless unique_strings.has_key?(sub_string)
      unique_strings[sub_string] = index

      if block.arity == 2
        block.call(sub_string,index)
      else
        block.call(sub_string)
      end
    end
  end

  return self
end

#format_bytes(options = {}) {|byte| ... } ⇒ String

Creates a new String by formatting each byte.

Examples:

"hello".format_bytes { |b| "%x" % b }
# => "68656c6c6f"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :include (#include?) — default: 0x00..0xff

    The bytes to format.

  • :exclude (#include?)

    The bytes not to format.

Yields:

  • (byte)

    The block which will return the formatted version of each byte within the String.

Yield Parameters:

  • byte (Integer)

    The byte to format.

Returns:

  • (String)

    The formatted version of the String.


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/ronin/formatting/extensions/text/string.rb', line 232

def format_bytes(options={})
  included  = (options[:include] || (0x00..0xff))
  excluded  = (options[:exclude] || Set[])
  formatted = ''

  each_byte do |b|
    formatted << if (included.include?(b) && !excluded.include?(b))
                   yield(b)
                 else
                   b
                 end
  end

  return formatted
end

#format_chars(options = {}) {|char| ... } ⇒ String

Creates a new String by formatting each character.

Examples:

"hello".format_chars { |c| c * 3 }
# => "hhheeellllllooo"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :include (#include?, Regexp) — default: /./m

    The bytes to format.

  • :exclude (#include?, Regexp)

    The bytes not to format.

Yields:

  • (char)

    The block which will return the formatted version of each character within the String.

Yield Parameters:

  • char (String)

    The character to format.

Returns:

  • (String)

    The formatted version of the String.


276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/ronin/formatting/extensions/text/string.rb', line 276

def format_chars(options={})
  included  = (options[:include] || /./m)
  excluded  = (options[:exclude] || Set[])
  formatted = ''

  matches = lambda { |filter,c|
    if filter.respond_to?(:include?)
      filter.include?(c)
    elsif filter.kind_of?(Regexp)
      c =~ filter
    end
  }

  each_char do |c|
    formatted << if (matches[included,c] && !matches[excluded,c])
                   yield(c)
                 else
                   c
                 end
  end

  return formatted
end

#format_html(options = {}) ⇒ String

Formats the chars in the String for HTML.

Examples:

"abc".format_html
# => "&#97;&#98;&#99;"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options for #format_chars.

Returns:

  • (String)

    The formatted HTML String.

See Also:

Since:

  • 0.2.0


97
98
99
100
101
102
103
104
105
106
# File 'lib/ronin/formatting/extensions/html/string.rb', line 97

def format_html(options={})
  formatter = if RUBY_VERSION < '1.9.'
                # String#ord was not backported to Ruby 1.8.7
                lambda { |c| c[0].format_html }
              else
                lambda { |c| c.ord.format_html }
              end

  format_chars(options,&formatter)
end

#format_http(options = {}) ⇒ String

Formats the bytes of the String.

Examples:

"hello".format_http
# => "%68%65%6c%6c%6f"

Returns:

  • (String)

    The HTTP hexadecimal encoded form of the String.

See Also:


106
107
108
# File 'lib/ronin/formatting/extensions/http/string.rb', line 106

def format_http(options={})
  format_bytes(options) { |b| b.format_http }
end

#format_js(options = {}) ⇒ String

Escapes a String for JavaScript.

Examples:

"hello".js_escape
# => "\\u0068\\u0065\\u006C\\u006C\\u006F"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options for #format_chars.

Returns:

  • (String)

    The JavaScript escaped String.

See Also:

Since:

  • 0.2.0


192
193
194
195
196
197
198
199
200
201
# File 'lib/ronin/formatting/extensions/html/string.rb', line 192

def format_js(options={})
  formatter = if RUBY_VERSION < '1.9.'
                # String#ord was not backported to Rub 1.8.7
                lambda { |c| c[0].format_js }
              else
                lambda { |c| c.ord.format_js }
              end

  format_chars(options,&formatter)
end

#fuzz(mutations = {}) {|fuzz| ... } ⇒ Enumerator

Incrementally fuzzes the String.

Examples:

Replace every e, i, o, u with (, 100 As and a \0:

"the quick brown fox".fuzz(/[eiou]/ => ['(', ('A' * 100), "\0"]) do |str|
  p str
end

"GET /".fuzz('/' => String.generate(['A', 1..100])) do |str|
  p str
end

Parameters:

Yields:

  • (fuzz)

    The given block will be passed every fuzzed String.

Yield Parameters:

  • fuzz (String)

    A fuzzed String.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.

Since:

  • 0.3.0


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/ronin/formatting/extensions/text/string.rb', line 161

def fuzz(mutations={})
  return enum_for(:fuzz,mutations) unless block_given?

  mutations.each do |pattern,substitution|
    pattern = case pattern
              when Regexp
                pattern
              when String
                Regexp.new(Regexp.escape(pattern))
              when Integer
                Regexp.new(pattern.chr)
              when Enumerable
                Regexp.union(pattern.map { |s| Regexp.escape(s.to_s) })
              else
                raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp")
              end

    scanner = StringScanner.new(self)
    indices = []

    while scanner.scan_until(pattern)
      indices << [scanner.pos - scanner.matched_size, scanner.matched_size]
    end

    indices.each do |index,length|
      substitution.each do |substitute|
        substitute = case substitute
                     when Proc
                       substitute.call(self[index,length])
                     when Integer
                       substitute.chr
                     else
                       substitute.to_s
                     end

        fuzzed = dup
        fuzzed[index,length] = substitute
        yield fuzzed
      end
    end
  end
end

#hex_escape(options = {}) ⇒ String

Hex-escapes characters in the String.

Examples:

"hello".hex_escape
# => "\\x68\\x65\\x6c\\x6c\\x6f"

Returns:

  • (String)

    The hex escaped version of the String.

See Also:


128
129
130
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 128

def hex_escape(options={})
  format_bytes(options) { |b| b.hex_escape }
end

#hex_unescapeString

Unescapes the hex-escaped String.

Examples:

"\\x68\\x65\\x6c\\x6c\\x6f".hex_unescape
# => "hello"

Returns:

  • (String)

    The unescaped version of the hex escaped String.


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 144

def hex_unescape
  buffer = ''
  hex_index = 0
  hex_length = length

  while (hex_index < hex_length)
    hex_substring = self[hex_index..-1]

    if hex_substring =~ /^\\[0-7]{3}/
      buffer << hex_substring[0..3].to_i(8)
      hex_index += 3
    elsif hex_substring =~ /^\\x[0-9a-fA-F]{1,2}/
      hex_substring[2..-1].scan(/^[0-9a-fA-F]{1,2}/) do |hex_byte|
        buffer << hex_byte.to_i(16)
        hex_index += (2 + hex_byte.length)
      end
    elsif hex_substring =~ /^\\./
      escaped_char = hex_substring[1..1]

      buffer << case escaped_char
                when '0'
                  "\0"
                when 'a'
                  "\a"
                when 'b'
                  "\b"
                when 't'
                  "\t"
                when 'n'
                  "\n"
                when 'v'
                  "\v"
                when 'f'
                  "\f"
                when 'r'
                  "\r"
                else
                  escaped_char
                end
      hex_index += 2
    else
      buffer << hex_substring[0]
      hex_index += 1
    end
  end

  return buffer
end

#html_escapeString

HTML escapes the String.

Examples:

"one & two".html_escape
# => "one &amp; two"

Returns:

  • (String)

    The HTML escaped String.

See Also:

Since:

  • 0.2.0


54
55
56
# File 'lib/ronin/formatting/extensions/html/string.rb', line 54

def html_escape
  CGI.escapeHTML(self)
end

#html_unescapeString

Unescapes the HTML encoded String.

Examples:

"&lt;p&gt;one &lt;span&gt;two&lt;/span&gt;&lt;/p&gt;".html_unescape
# => "<p>one <span>two</span></p>"

Returns:

  • (String)

    The unescaped String.

See Also:

Since:

  • 0.2.0


74
75
76
# File 'lib/ronin/formatting/extensions/html/string.rb', line 74

def html_unescape
  CGI.unescapeHTML(self)
end

#insert_after(pattern, data) ⇒ String

Inserts data after the occurrence of a pattern.

Parameters:

  • pattern (String, Regexp)

    The pattern to search for.

  • data (String)

    The data to insert after the pattern.

Returns:

  • (String)

    The new modified String.


370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/ronin/formatting/extensions/text/string.rb', line 370

def insert_after(pattern,data)
  string = dup
  match  = string.match(pattern)

  if match
    index = match.end(match.length - 1)

    string.insert(index,data)
  end

  return string
end

#insert_before(pattern, data) ⇒ String

Inserts data before the occurrence of a pattern.

Parameters:

  • pattern (String, Regexp)

    The pattern to search for.

  • data (String)

    The data to insert before the pattern.

Returns:

  • (String)

    The new modified String.


348
349
350
351
352
353
354
# File 'lib/ronin/formatting/extensions/text/string.rb', line 348

def insert_before(pattern,data)
  string = dup
  index  = string.index(pattern)

  string.insert(index,data) if index
  return string
end

#js_escape(options = {}) ⇒ String

Escapes a String for JavaScript.

Examples:

"hello\nworld\n".js_escape
# => "hello\\nworld\\n"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options for #format_chars.

Returns:

  • (String)

    The JavaScript escaped String.

See Also:

Since:

  • 0.2.0


127
128
129
130
131
132
133
134
135
136
# File 'lib/ronin/formatting/extensions/html/string.rb', line 127

def js_escape(options={})
  formatter = if RUBY_VERSION < '1.9.'
                # String#ord was not backported to Rub 1.8.7
                lambda { |c| c[0].js_escape }
              else
                lambda { |c| c.ord.js_escape }
              end

  format_chars(options,&formatter)
end

#js_unescapeString

Unescapes a JavaScript escaped String.

Examples:

"\\u0068\\u0065\\u006C\\u006C\\u006F world".js_unescape
# => "hello world"

Returns:

  • (String)

    The unescaped JavaScript String.

Since:

  • 0.2.0


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ronin/formatting/extensions/html/string.rb', line 152

def js_unescape
  unescaped = ''

  scan(/([\\%]u[0-9a-fA-F]{4}|[\\%][0-9a-fA-F]{2}|\\[btnfr"\\]|.)/).each do |match|
    c = match[0]

    unescaped << case c.length
                 when 6
                   c[2,4].to_i(16)
                 when 3
                   c[1,2].to_i(16)
                 when 2
                   JS_BACKSLASHED_CHARS[c]
                 else
                   c
                 end
  end

  return unescaped
end

#md5String

Returns The MD5 checksum of the String.

Examples:

"hello".md5
# => "5d41402abc4b2a76b9719d911017c592"

Returns:

  • (String)

    The MD5 checksum of the String.


36
37
38
# File 'lib/ronin/formatting/extensions/digest/string.rb', line 36

def md5
  Digest::MD5.hexdigest(self)
end

#pad(padding, max_length = length) ⇒ String

Creates a new String by padding the String with repeating text, out to a specified length.

Examples:

"hello".pad('A',50)
# => "helloAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

Parameters:

  • padding (String)

    The text to pad the new String with.

  • max_length (String) (defaults to: length)

    The maximum length to pad the new String out to.

Returns:

  • (String)

    The padded version of the String.


402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/ronin/formatting/extensions/text/string.rb', line 402

def pad(padding,max_length=length)
  padding = padding.to_s

  if max_length > length
    max_length -= length
  else
    max_length = 0
  end

  padded = self + (padding * (max_length / padding.length))

  unless (remaining = (max_length % padding.length)) == 0
    padded << padding[0,remaining]
  end

  return padded
end

#random_case(options = {}) ⇒ Object

Creates a new String by randomizing the case of each character in the String.

Examples:

"get out your checkbook".random_case
# => "gEt Out YOur CHEckbook"

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :include (Array, Range) — default: 0x00..0xff

    The bytes to format.

  • :exclude (Array, Range)

    The bytes not to format.

  • :probability (Float) — default: 0.5

    The probability that a character will have it's case changed.


322
323
324
325
326
327
328
329
330
331
332
# File 'lib/ronin/formatting/extensions/text/string.rb', line 322

def random_case(options={})
  prob = (options[:probability] || 0.5)

  format_chars(options) do |c|
    if rand <= prob
      c.swapcase 
    else
      c
    end
  end
end

#sha1String Also known as: sha128

Returns The SHA1 checksum of the String.

Examples:

"hello".sha1
# => "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d"

Returns:

  • (String)

    The SHA1 checksum of the String.


50
51
52
# File 'lib/ronin/formatting/extensions/digest/string.rb', line 50

def sha1
  Digest::SHA1.hexdigest(self)
end

#sha256String Also known as: sha2

Returns The SHA2 checksum of the String.

Examples:

"hello".sha2
# => "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

Returns:

  • (String)

    The SHA2 checksum of the String.


66
67
68
# File 'lib/ronin/formatting/extensions/digest/string.rb', line 66

def sha256
  Digest::SHA256.hexdigest(self)
end

#sha512String

Returns The SHA512 checksum of the String.

Examples:

"hello".sha512
# => "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"

Returns:

  • (String)

    The SHA512 checksum of the String.


82
83
84
# File 'lib/ronin/formatting/extensions/digest/string.rb', line 82

def sha512
  Digest::SHA512.hexdigest(self)
end

#sql_decodeObject

Returns the SQL decoded form of the String.

Examples:

"'Conan O''Brian'".sql_decode
# => "Conan O'Brian"
"0x2f6574632f706173737764".sql_decode
# => "/etc/passwd"

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/ronin/formatting/extensions/sql/string.rb', line 82

def sql_decode
  if ((self[0...2] == '0x') && (length % 2 == 0))
    raw = ''

    self[2..-1].scan(/[0-9a-fA-F]{2}/).each do |hex_char|
      raw << hex_char.hex.chr
    end

    return raw
  elsif (self[0..0] == "'" && self[-1..-1] == "'")
    self[1..-2].gsub("\\'","'").gsub("''","'")
  else
    return self
  end
end

#sql_encodeObject

Returns the SQL hex-string encoded form of the String.

Examples:

"/etc/passwd".sql_encode
# => "0x2f6574632f706173737764"

59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ronin/formatting/extensions/sql/string.rb', line 59

def sql_encode
  return '' if empty?

  hex_string = '0x'

  each_byte do |b|
    hex_string << ('%.2x' % b)
  end

  return hex_string
end

#sql_escape(quotes = :single) ⇒ String

Escapes an String for SQL.

Examples:

"O'Brian".sql_escape
# => "'O''Brian'"

Parameters:

  • quotes (Symbol) (defaults to: :single)

    (:single) Specifies whether to create a single or double quoted string. May be either :single or :double.

Returns:

  • (String)

    The escaped String.

Raises:

  • (ArgumentError)

    The quotes argument was neither :single nor :double.

Since:

  • 0.3.0


41
42
43
44
45
46
47
48
49
50
# File 'lib/ronin/formatting/extensions/sql/string.rb', line 41

def sql_escape(quotes=:single)
  case quotes
  when :single
    "'#{gsub(/'/,"''")}'"
  when :double
    "\"#{gsub(/"/,'""')}\""
  else
    raise(ArgumentError,"invalid quoting style #{quotes.inspect}")
  end
end

#uncommon_substring(other) ⇒ String

Finds the uncommon substring within the specified other string, which does not occur within the string.

Parameters:

  • other (String)

    The other String to compare against.

Returns:

  • (String)

    The uncommon substring between the two Strings.


189
190
191
192
193
194
# File 'lib/ronin/extensions/string.rb', line 189

def uncommon_substring(other)
  prefix  = common_prefix(other)
  postfix = self[prefix.length..-1].common_suffix(other[prefix.length..-1])

  return self[prefix.length...(length - postfix.length)]
end

#unhexdump(options = {}) ⇒ String

Converts a multitude of hexdump formats back into raw-data.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Options Hash (options):

  • :format (Symbol)

    The expected format of the hexdump. Must be either :od or :hexdump.

  • :encoding (Symbol)

    Denotes the encoding used for the bytes within the hexdump. Must be one of the following:

    • :binary
    • :octal
    • :octal_bytes
    • :octal_shorts
    • :octal_ints
    • :octal_quads
    • :decimal
    • :decimal_bytes
    • :decimal_shorts
    • :decimal_ints
    • :decimal_quads
    • :hex
    • :hex_bytes
    • :hex_shorts
    • :hex_ints
    • :hex_quads
  • :segment (Integer) — default: 16

    The length in bytes of each segment in the hexdump.

Returns:

  • (String)

    The raw-data from the hexdump.


334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 334

def unhexdump(options={})
  case (format = options[:format])
  when :od
    address_base = 8
    base         = 8
    word_size    = 2
  when :hexdump
    address_base = 16
    base         = 16
    word_size    = 2
  else
    address_base = 16
    base         = 16
    word_size    = 1
  end

  case options[:encoding]
  when :binary
    base = 2
  when :octal, :octal_bytes, :octal_shorts, :octal_ints, :octal_quads
    base = 8
  when :decimal, :decimal_bytes, :decimal_shorts, :decimal_ints, :decimal_quads
    base = 10
  when :hex, :hex_bytes, :hex_shorts, :hex_ints, :hex_quads
    base = 16
  end

  case options[:encoding]
  when :binary, :octal_bytes, :decimal_bytes, :hex_bytes
    word_size = 1
  when :octal_shorts, :decimal_shorts, :hex_shorts
    word_size = 2
  when :octal_ints, :decimal_ints, :hex_ints
    word_size = 4
  when :octal_quads, :decimal_quads, :hex_quads
    word_size = 8
  end

  current_addr = last_addr = first_addr = nil
  repeated = false

  segment_length = (options[:segment] || 16)
  segment = []
  buffer = []

  each_line do |line|
    if format == :hexdump
      line = line.gsub(/\s+\|.+\|\s*$/,'')
    end

    words = line.split

    if words.first == '*'
      repeated = true
    elsif words.length > 0
      current_addr = words.shift.to_i(address_base)
      first_addr ||= current_addr

      if repeated
        (((current_addr - last_addr) / segment.length) - 1).times do
          buffer += segment
        end

        repeated = false
      end

      segment.clear

      words.each do |word|
        if (base != 10 && word =~ /^(\\[0abtnvfr\\]|.)$/)
          word.hex_unescape.each_byte { |b| segment << b }
        else
          segment += word.to_i(base).bytes(word_size)
        end
      end

      segment = segment[0,segment_length]
      buffer += segment
      last_addr = current_addr
    end
  end

  return buffer[0,(last_addr - first_addr)]
end

#uri_decodeString

URI decodes the String.

Examples:

"genre%3f".uri_decode
# => "genre?"

Returns:

  • (String)

    The decoded URI form of the String.


56
57
58
# File 'lib/ronin/formatting/extensions/http/string.rb', line 56

def uri_decode
  URI.decode(self)
end

#uri_encodeString

URI encodes the String.

Examples:

"art is graffiti".uri_encode
# => "art%20is%20graffiti"

Returns:

  • (String)

    The URI encoded form of the String.


40
41
42
# File 'lib/ronin/formatting/extensions/http/string.rb', line 40

def uri_encode
  URI.encode(self)
end

#uri_escapeString

URI escapes the String.

Examples:

"x > y".uri_escape
# => "x+%3E+y"

Returns:

  • (String)

    The URI escaped form of the String.


72
73
74
# File 'lib/ronin/formatting/extensions/http/string.rb', line 72

def uri_escape
  CGI.escape(self)
end

#uri_unescapeString

URI unescapes the String.

Examples:

"sweet+%26+sour".uri_unescape
# => "sweet & sour"

Returns:

  • (String)

    The unescaped URI form of the String.


88
89
90
# File 'lib/ronin/formatting/extensions/http/string.rb', line 88

def uri_unescape
  CGI.unescape(self)
end

#xor(key) ⇒ String

XOR encodes the String.

Examples:

"hello".xor(0x41)
# => ")$--."
"hello again".xor([0x55, 0x41, 0xe1])
# => "=$\x8d9.\xc14&\x80</"

Parameters:

Returns:

  • (String)

    The XOR encoded String.


212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 212

def xor(key)
  key = case key
        when Integer
          [key]
        when String
          key.bytes
        else
          key
        end

  key    = key.cycle
  result = ''

  bytes.each do |b|
    result << (b ^ key.next).chr
  end

  return result
end

#zlib_deflateString

Zlib deflate a string.

Examples:

"hello".zlib_deflate
# => "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15"

Returns:

  • (String)

    The Zlib deflated form of the string.


292
293
294
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 292

def zlib_deflate
  Zlib::Deflate.deflate(self)
end

#zlib_inflateString

Zlib inflate a string.

Examples:

"x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15".zlib_inflate
# => "hello"

Returns:

  • (String)

    The Zlib inflated form of the string.


276
277
278
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 276

def zlib_inflate
  Zlib::Inflate.inflate(self)
end