Class: String
- Defined in:
- lib/ronin/extensions/string.rb,
lib/ronin/fuzzing/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-2021 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 https://www.gnu.org/licenses/.
Constant Summary collapse
- ESCAPE_BYTES =
Special ASCII bytes and their escaped character forms
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", "\\\"" => "\"", "\\\\" => "\\" }
- UNESCAPE_CHARS =
Common escaped characters.
Hash.new do |hash,char| if char[0,1] == '\\' char[1,1] else char end end
Class Method Summary collapse
-
.generate(*fields) {|string| ... } ⇒ Enumerator
Generate permutations of Strings from a format template.
Instance Method Summary collapse
-
#base64_decode(mode = nil) ⇒ String
Base64 decodes a string.
-
#base64_encode(mode = nil) ⇒ String
Base64 encodes a string.
-
#common_postfix(other) ⇒ Object
deprecated
Deprecated.
Deprecates as of 0.2.0, and will be removed in 1.0.0. Please use #common_suffix instead.
-
#common_prefix(other) ⇒ String
The common prefix of the string and the specified other string.
-
#common_suffix(other) ⇒ String
Finds the common suffix of the string and the specified other string.
-
#depack(arch, address_length = nil) ⇒ Integer
deprecated
Deprecated.
Deprecated as of 0.5.0, use #unpack instead.
-
#dump ⇒ String
(also: #inspect, #escape)
Dumps the string as a C-style string.
-
#each_substring(min = 1) {|substring, (index)| ... } ⇒ String
Enumerates over every sub-string within the string.
-
#each_unique_substring(min = 1) {|substring, (index)| ... } ⇒ String
Enumerates over the unique sub-strings contained in the string.
-
#format_bytes(options = {}) {|byte| ... } ⇒ String
Creates a new String by formatting each byte.
-
#format_chars(options = {}) {|char| ... } ⇒ String
Creates a new String by formatting each character.
-
#format_html(options = {}) ⇒ String
Formats the chars in the String for HTML.
-
#format_http(options = {}) ⇒ String
Formats the bytes of the String.
-
#format_js(options = {}) ⇒ String
Escapes a String for JavaScript.
-
#fuzz(substitutions = {}) {|fuzz| ... } ⇒ Enumerator
Incrementally fuzzes the String.
-
#hex_escape(options = {}) ⇒ String
Hex-escapes characters in the String.
-
#html_escape ⇒ String
HTML escapes the String.
-
#html_unescape ⇒ String
Unescapes the HTML encoded String.
-
#insert_after(pattern, data) ⇒ String
Inserts data after the occurrence of a pattern.
-
#insert_before(pattern, data) ⇒ String
Inserts data before the occurrence of a pattern.
-
#js_escape(options = {}) ⇒ String
Escapes a String for JavaScript.
-
#js_unescape ⇒ String
Unescapes a JavaScript escaped String.
-
#md5 ⇒ String
The MD5 checksum of the String.
-
#mutate(mutations = {}) {|mutant| ... } ⇒ Enumerator
Permutes over every possible mutation of the String.
-
#pad(padding, max_length = length) ⇒ String
Creates a new String by padding the String with repeating text, out to a specified length.
-
#random_case(options = {}) ⇒ Object
Creates a new String by randomizing the case of each character in the String.
-
#repeating(lengths) {|repeated| ... } ⇒ Enumerator
Repeats the String.
-
#sha1 ⇒ String
(also: #sha128)
The SHA1 checksum of the String.
-
#sha256 ⇒ String
(also: #sha2)
The SHA2 checksum of the String.
-
#sha512 ⇒ String
The SHA512 checksum of the String.
-
#sql_decode ⇒ Object
Returns the SQL decoded form of the String.
-
#sql_encode ⇒ Object
Returns the SQL hex-string encoded form of the String.
-
#sql_escape(quotes = :single) ⇒ String
Escapes an String for SQL.
-
#sql_inject ⇒ String
Prepares the String for injection into a SQL expression.
-
#uncommon_substring(other) ⇒ String
Finds the uncommon sub-string within the specified other string, which does not occur within the string.
-
#unescape ⇒ String
(also: #hex_unescape)
Unescapes the escaped String.
-
#unhexdump(options = {}) ⇒ String
Converts a multitude of hexdump formats back into raw-data.
-
#unpack(*arguments) ⇒ Array
Unpacks the String.
-
#unpack_original ⇒ Object
-
#uri_decode ⇒ String
URI decodes the String.
-
#uri_encode ⇒ String
URI encodes the String.
-
#uri_escape ⇒ String
URI escapes the String.
-
#uri_unescape ⇒ String
URI unescapes the String.
-
#xor(key) ⇒ String
XOR encodes the String.
-
#zlib_deflate ⇒ String
Zlib deflate a string.
-
#zlib_inflate ⇒ String
Zlib inflate a string.
Class Method Details
Instance Method Details
#base64_decode(mode = nil) ⇒ String
mode
argument is only available on Ruby >= 1.9.
Base64 decodes a string.
255 256 257 258 259 260 261 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 255 def base64_decode(mode=nil) case mode when :strict then Base64.strict_decode64(self) when :url, :urlsafe then Base64.urlsafe_decode64(self) else Base64.decode64(self) end end |
#base64_encode(mode = nil) ⇒ String
Base64 encodes a string.
225 226 227 228 229 230 231 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 225 def base64_encode(mode=nil) case mode when :strict then Base64.strict_encode64(self) when :url, :urlsafe then Base64.urlsafe_encode64(self) else Base64.encode64(self) end end |
#common_postfix(other) ⇒ Object
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.
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.
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
Deprecated as of 0.5.0, use #unpack instead.
Unpacks the String into an Integer.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 110 def depack(arch,address_length=nil) if arch.kind_of?(String) return 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 |
#dump ⇒ String Also known as: inspect, escape
This method is only defined on Ruby 1.8.x.
Dumps the string as a C-style string.
230 231 232 233 234 235 |
# File 'lib/ronin/extensions/string.rb', line 230 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.
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(__method__,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.
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(__method__,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.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 52 def format_bytes(={}) included = ([:include] || (0x00..0xff)) excluded = ([: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.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 96 def format_chars(={}) included = ([:include] || /./m) excluded = ([:exclude] || Set[]) formatted = '' matches = lambda { |filter,c| if filter.respond_to?(:include?) then filter.include?(c) elsif filter.kind_of?(Regexp) then 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.
97 98 99 100 101 102 103 104 |
# File 'lib/ronin/formatting/extensions/html/string.rb', line 97 def format_html(={}) # String#ord was not backported to Ruby 1.8.7 formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].format_html } else lambda { |c| c.ord.format_html } end format_chars(,&formatter) end |
#format_http(options = {}) ⇒ String
Formats the bytes of the String.
106 107 108 |
# File 'lib/ronin/formatting/extensions/http/string.rb', line 106 def format_http(={}) format_bytes() { |b| b.format_http } end |
#format_js(options = {}) ⇒ String
Escapes a String for JavaScript.
185 186 187 188 189 190 191 192 |
# File 'lib/ronin/formatting/extensions/html/string.rb', line 185 def format_js(={}) # String#ord was not backported to Rub 1.8.7 formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].format_js } else lambda { |c| c.ord.format_js } end format_chars(,&formatter) end |
#fuzz(substitutions = {}) {|fuzz| ... } ⇒ Enumerator
Incrementally fuzzes the String.
173 174 175 |
# File 'lib/ronin/fuzzing/extensions/string.rb', line 173 def fuzz(substitutions={},&block) Ronin::Fuzzing::Fuzzer.new(substitutions).each(self,&block) end |
#hex_escape(options = {}) ⇒ String
Hex-escapes characters in the String.
164 165 166 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 164 def hex_escape(={}) format_bytes() { |b| b.hex_escape } end |
#html_escape ⇒ String
HTML escapes the String.
54 55 56 |
# File 'lib/ronin/formatting/extensions/html/string.rb', line 54 def html_escape CGI.escapeHTML(self) end |
#html_unescape ⇒ String
Unescapes the HTML encoded String.
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.
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 186 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.
164 165 166 167 168 169 170 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 164 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.
125 126 127 128 129 130 131 132 |
# File 'lib/ronin/formatting/extensions/html/string.rb', line 125 def js_escape(={}) # String#ord was not backported to Rub 1.8.7 formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].js_escape } else lambda { |c| c.ord.js_escape } end format_chars(,&formatter) end |
#js_unescape ⇒ String
Unescapes a JavaScript escaped String.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ronin/formatting/extensions/html/string.rb', line 148 def js_unescape unescaped = '' scan(/[\\%]u[0-9a-fA-F]{1,4}|[\\%][0-9a-fA-F]{1,2}|\\[btnfr"\\]|./) do |c| unescaped << JS_BACKSLASHED_CHARS.fetch(c) do if (c.start_with?("\\u") || c.start_with?("%u")) c[2..-1].to_i(16) elsif (c.start_with?("\\") || c.start_with?("%")) c[1..-1].to_i(16) else c end end end return unescaped end |
#md5 ⇒ String
Returns 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 |
#mutate(mutations = {}) {|mutant| ... } ⇒ Enumerator
Permutes over every possible mutation of the String.
205 206 207 |
# File 'lib/ronin/fuzzing/extensions/string.rb', line 205 def mutate(mutations={},&block) Ronin::Fuzzing::Mutator.new(mutations).each(self,&block) end |
#pad(padding, max_length = length) ⇒ String
Creates a new String by padding the String with repeating text, out to a specified length.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 218 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.
140 141 142 143 144 145 146 147 148 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 140 def random_case(={}) prob = ([:probability] || 0.5) format_chars() do |c| if rand <= prob then c.swapcase else c end end end |
#repeating(lengths) {|repeated| ... } ⇒ Enumerator
Repeats the String.
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ronin/fuzzing/extensions/string.rb', line 128 def repeating(lengths,&block) case lengths when Integer # if lengths is an Integer, simply multiply the String and return repeated = (self * lengths) yield repeated if block_given? return repeated else return Ronin::Fuzzing::Repeater.new(lengths).each(self,&block) end end |
#sha1 ⇒ String Also known as: sha128
Returns 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 |
#sha256 ⇒ String Also known as: sha2
Returns 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 |
#sha512 ⇒ String
Returns 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_decode ⇒ Object
Returns the SQL decoded form of the String.
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 (start_with?('0x') && (length % 2 == 0)) raw = '' self[2..-1].scan(/../) do |hex_char| raw << hex_char.to_i(16).chr end return raw elsif (start_with?("'") && end_with?("'")) self[1..-2].gsub(/\\'|''/,"'") else return self end end |
#sql_encode ⇒ Object
Returns the SQL hex-string encoded form of the String.
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.
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ronin/formatting/extensions/sql/string.rb', line 40 def sql_escape(quotes=:single) char = case quotes when :single then "'" when :double then '"' when :tick then '`' else raise(ArgumentError,"invalid quoting style #{quotes.inspect}") end return char + gsub(char,char * 2) + char end |
#sql_inject ⇒ String
Prepares the String for injection into a SQL expression.
120 121 122 123 124 125 126 127 128 |
# File 'lib/ronin/formatting/extensions/sql/string.rb', line 120 def sql_inject if (start_with?("'") || start_with?('"') || start_with?('`')) if self[0,1] == self[-1,1] then self[1..-2] else "#{self[1..-1]}--" end else self end end |
#uncommon_substring(other) ⇒ String
Finds the uncommon sub-string within the specified other string, which does not occur within the string.
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 |
#unescape ⇒ String Also known as: hex_unescape
Unescapes the escaped String.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/ronin/formatting/extensions/text/string.rb', line 269 def 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,4].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 =~ /^\\./ buffer << UNESCAPE_CHARS[hex_substring[0,2]] hex_index += 2 else buffer << hex_substring[0,1] hex_index += 1 end end return buffer end |
#unhexdump(options = {}) ⇒ String
Converts a multitude of hexdump formats back into raw-data.
341 342 343 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 341 def unhexdump(={}) Ronin::Binary::Hexdump::Parser.new().parse(self) end |
#unpack(*arguments) ⇒ Array
Unpacks the String.
63 64 65 66 67 68 69 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 63 def unpack(*arguments) if (arguments.length == 1 && arguments.first.kind_of?(String)) unpack_original(arguments.first) else unpack_original(Ronin::Binary::Template.compile(arguments)) end end |
#unpack_original ⇒ Object
34 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 34 alias unpack_original unpack |
#uri_decode ⇒ String
URI decodes the String.
56 57 58 |
# File 'lib/ronin/formatting/extensions/http/string.rb', line 56 def uri_decode URI::DEFAULT_PARSER.unescape(self) end |
#uri_encode ⇒ String
URI encodes the String.
40 41 42 |
# File 'lib/ronin/formatting/extensions/http/string.rb', line 40 def uri_encode URI::DEFAULT_PARSER.escape(self) end |
#uri_escape ⇒ String
URI escapes the String.
72 73 74 |
# File 'lib/ronin/formatting/extensions/http/string.rb', line 72 def uri_escape CGI.escape(self) end |
#uri_unescape ⇒ String
URI unescapes 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.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 189 def xor(key) key = case key when Integer then [key] when String then key.bytes else key end key = key.cycle result = '' bytes.each do |b| result << (b ^ key.next).chr end return result end |
#zlib_deflate ⇒ String
Zlib deflate a string.
291 292 293 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 291 def zlib_deflate Zlib::Deflate.deflate(self) end |
#zlib_inflate ⇒ String
Zlib inflate a string.
275 276 277 |
# File 'lib/ronin/formatting/extensions/binary/string.rb', line 275 def zlib_inflate Zlib::Inflate.inflate(self) end |