Module: Ronin::Support::Encoding::Hex

Defined in:
lib/ronin/support/encoding/hex.rb

Overview

Since:

  • 1.0.0

Constant Summary collapse

BACKSLASHED_CHARS =

Backslash escaped characters.

Since:

  • 1.0.0

{
  "\\" => '\\',
  '"'  => '"',
  '0'  => "\0",
  'a'  => "\a",
  'b'  => "\b",
  't'  => "\t",
  'n'  => "\n",
  'v'  => "\v",
  'f'  => "\f",
  'r'  => "\r"
}

Class Method Summary collapse

Class Method Details

.decode(data) ⇒ String

Hex decodes the String.

Examples:

Encoding::Hex.decode("68656C6C6F")
# => "hello"

Parameters:

  • data (String)

    The given data to hex decode.

Returns:

  • (String)

    The hex decoded version of the String.

Since:

  • 1.0.0



127
128
129
130
131
132
133
134
135
# File 'lib/ronin/support/encoding/hex.rb', line 127

def self.decode(data)
  decoded = String.new

  data.scan(/../) do |hex|
    decoded << hex.to_i(16).chr
  end

  return decoded
end

.encode(data) ⇒ String

Hex encodes the given data.

Examples:

Encoding::Hex.encode("hello")
# => "68656C6C6F"

Parameters:

  • data (String)

    The given data to hex encode.

Returns:

  • (String)

    The hex encoded version of the String.

Since:

  • 1.0.0



104
105
106
107
108
109
110
111
112
# File 'lib/ronin/support/encoding/hex.rb', line 104

def self.encode(data)
  encoded = String.new

  data.each_byte do |byte|
    encoded << encode_byte(byte)
  end

  return encoded
end

.encode_byte(byte) ⇒ String

Hex encodes the given byte.

Examples:

Encoding::Hex.encode_byte(0x41)
# => "41"

Parameters:

  • byte (Integer)

    The byte to hex encode.

Returns:

  • (String)

    The hex encoded version of the byte.

Since:

  • 1.0.0



53
54
55
# File 'lib/ronin/support/encoding/hex.rb', line 53

def self.encode_byte(byte)
  "%.2x" % byte
end

.escape(data) ⇒ String

Hex-escapes the given data.

Examples:

Encoding::Hex.escape("hello")
# => "\\x68\\x65\\x6c\\x6c\\x6f"

Parameters:

  • data (String)

    The given data to hex escape.

Returns:

  • (String)

    The hex escaped version of the String.

Since:

  • 1.0.0



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

def self.escape(data)
  escaped = String.new

  if data.valid_encoding?
    data.each_codepoint do |codepoint|
      escaped << escape_byte(codepoint)
    end
  else
    data.each_byte do |byte|
      escaped << escape_byte(byte)
    end
  end

  return escaped
end

.escape_byte(byte) ⇒ String

Hex escapes the given byte.

Examples:

Encoding::Hex.escape_byte(42)
# => "\\x2a"

Parameters:

  • byte (Integer)

    The byte value to hex escape.

Returns:

  • (String)

    The hex escaped version of the Integer.

Raises:

  • (RangeError)

    The byte value is negative.

Since:

  • 1.0.0



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ronin/support/encoding/hex.rb', line 73

def self.escape_byte(byte)
  if byte >= 0x00 && byte <= 0xff
    if    byte == 0x22
      "\\\""
    elsif byte == 0x5d
      "\\\\"
    elsif byte >= 0x20 && byte <= 0x7e
      byte.chr
    else
      "\\x%.2x" % byte
    end
  elsif byte > 0xff
    "\\x%x" % byte
  else
    raise(RangeError,"#{byte.inspect} out of char range")
  end
end

.quote(data) ⇒ String

Converts the given data into a double-quoted hex string.

Examples:

Encoding::Hex.quote("hello\nworld")
# => "\"hello\\nworld\""

Parameters:

  • data (String)

    The given data to hex-escape and double-quote.

Returns:

  • (String)

    The double-quoted and hex escaped string.

Since:

  • 1.0.0



229
230
231
# File 'lib/ronin/support/encoding/hex.rb', line 229

def self.quote(data)
  "\"#{escape(data)}\""
end

.unescape(data) ⇒ String

Removes the quotes an unescapes a quoted hex string.

Examples:

Encoding::Hex.unescape("hello\\nworld")
# => "hello\nworld"

Parameters:

  • data (String)

    The quoted and hex escaped hex string.

Returns:

  • (String)

    The un-quoted String if the String begins and ends with quotes, or the same String if it is not quoted.

Since:

  • 1.0.0



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/ronin/support/encoding/hex.rb', line 194

def self.unescape(data)
  buffer  = String.new(encoding: Encoding::UTF_8)
  scanner = StringScanner.new(data)

  until scanner.eos?
    buffer << case (char = scanner.getch)
              when '\\'
                if (hex_escape    = scanner.scan(/x[0-9a-fA-F]{4,8}/))
                  hex_escape[1..].to_i(16).chr(Encoding::UTF_8)
                elsif (hex_escape = scanner.scan(/x[0-9a-fA-F]{1,2}/))
                  hex_escape[1..].to_i(16).chr
                elsif (char       = scanner.getch)
                  BACKSLASHED_CHARS.fetch(char,char)
                end
              else
                char
              end
  end

  return buffer
end

.unquote(data) ⇒ String

Removes the quotes and unescapes a hex string.

Examples:

Encoding::Hex.unquote("\"hello\\nworld\"")
# => "hello\nworld"

Parameters:

  • data (String)

    The quoted hex String to unescape and unquote.

Returns:

  • (String)

    The un-quoted String if the String begins and ends with quotes, or the same String if it is not quoted.

Since:

  • 1.0.0



247
248
249
250
251
252
253
254
# File 'lib/ronin/support/encoding/hex.rb', line 247

def self.unquote(data)
  if ((data[0] == '"' && data[-1] == '"') ||
      (data[0] == "'" && data[-1] == "'"))
    unescape(data[1..-2])
  else
    data
  end
end