diff --git a/.rubocop.yml b/.rubocop.yml index 76358af..daf920f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,7 +2,10 @@ AllCops: TargetRubyVersion: 2.4 -Layout/AlignHash: +Layout/HashAlignment: + Include: + - 'lib/**/*.rb' +Layout/LineLength: Include: - 'lib/**/*.rb' Metrics/AbcSize: @@ -11,9 +14,6 @@ Metrics/ClassLength: Max: 200 Metrics/CyclomaticComplexity: Enabled: false -Metrics/LineLength: - Include: - - 'lib/**/*.rb' Metrics/BlockNesting: Exclude: - 'bin/*' diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..24ba9a3 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.7.0 diff --git a/Gemfile.lock b/Gemfile.lock index a096a47..c8df9dc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - ctf-party (1.0.0) + ctf-party (1.1.0) GEM remote: https://rubygems.org/ @@ -38,15 +38,15 @@ PLATFORMS ruby DEPENDENCIES - bundler (~> 2.0) + bundler (~> 2.1) commonmarker (~> 0.20) ctf-party! github-markup (~> 3.0) - minitest (~> 5.11) + minitest (~> 5) rake (~> 13.0) - redcarpet (~> 3.4) - rubocop (~> 0.63) + redcarpet (~> 3.5) + rubocop (~> 0.79) yard (~> 0.9) BUNDLED WITH - 2.0.2 + 2.1.4 diff --git a/README.md b/README.md index 9c4a792..0344bf3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ security researchers, bug bounty hunters, pentesters but mostly focused on CTF) by patching the String class to add a short syntax of usual code patterns. The philosophy is also to keep the library to be pure ruby (no dependencies) and not to re-implement what another library is already doing well -(eg.[xorcist] for xor). +(eg. [xorcist] for xor). [xorcist]:https://github.com/fny/xorcist @@ -47,6 +47,7 @@ myvar.to_b64! - digest: `md5`, `md5!`, `sha1`, `sha1!`, etc. - flag: `flag`, `flag!`, `flag?` (apply/check a flag format) - rot: `rot`, `rot!`, `rot13`, `rot13!` +- hex: `hex2dec`, `dec2hex`, `to_hex`, `from_hex` and bang versions ## References diff --git a/ctf_party.gemspec b/ctf_party.gemspec index 176fecf..7337681 100644 --- a/ctf_party.gemspec +++ b/ctf_party.gemspec @@ -41,12 +41,12 @@ Gem::Specification.new do |s| s.required_ruby_version = '~> 2.4' - s.add_development_dependency('bundler', '~> 2.0') + s.add_development_dependency('bundler', '~> 2.1') s.add_development_dependency('commonmarker', '~> 0.20') # for GMF support in YARD s.add_development_dependency('github-markup', '~> 3.0') # for GMF support in YARD - s.add_development_dependency('minitest', '~> 5.11') + s.add_development_dependency('minitest', '~> 5') s.add_development_dependency('rake', '~> 13.0') - s.add_development_dependency('redcarpet', '~> 3.4') # for GMF support in YARD - s.add_development_dependency('rubocop', '~> 0.63') + s.add_development_dependency('redcarpet', '~> 3.5') # for GMF support in YARD + s.add_development_dependency('rubocop', '~> 0.79') s.add_development_dependency('yard', '~> 0.9') end diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 80fd69a..eec2627 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [1.1.0] + +**Features** + +- new hexadecimal methods: + - normal: `hex2dec`, `dec2hex`, `to_hex`, `from_hex` + - in-place: `hex2dec!`, `dec2hex!`, `to_hex!`, `from_hex!` + +**Code** + +- `to_b64!` and `from_b64!` code simplification +- yard internal references from implicit to explicit + +**Chore** + +- Updated dependencies +- Updated rubocop rules + ## [1.0.0] - Initial version diff --git a/docs/README.md b/docs/README.md index a1f231d..e05ae0e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,7 +14,7 @@ security researchers, bug bounty hunters, pentesters but mostly focused on CTF) by patching the String class to add a short syntax of usual code patterns. The philosophy is also to keep the library to be pure ruby (no dependencies) and not to re-implement what another library is already doing well -(eg.[xorcist] for xor). +(eg. [xorcist] for xor). [xorcist]:https://github.com/fny/xorcist @@ -42,6 +42,7 @@ myvar.to_b64! - digest: `md5`, `md5!`, `sha1`, `sha1!`, etc. - flag: `flag`, `flag!`, `flag?` (apply/check a flag format) - rot: `rot`, `rot!`, `rot13`, `rot13!` +- hex: `hex2dec`, `dec2hex`, `to_hex`, `from_hex` and bang versions ## References diff --git a/docs/yard/String.html b/docs/yard/String.html index d23e120..ba651d5 100644 --- a/docs/yard/String.html +++ b/docs/yard/String.html @@ -6,15 +6,15 @@ Class: String - — Documentation by YARD 0.9.20 + — Documentation by YARD 0.9.23 - + - + - @@ -94,8 +94,8 @@
Defined in:
-
lib/ctf_party/rot.rb,
- lib/ctf_party/flag.rb,
lib/ctf_party/base64.rb,
lib/ctf_party/digest.rb
+
lib/ctf_party/hex.rb,
+ lib/ctf_party/rot.rb,
lib/ctf_party/flag.rb,
lib/ctf_party/base64.rb,
lib/ctf_party/digest.rb
@@ -226,6 +226,54 @@

Is the string encoded in base64?.

+ + + +
  • + + + #dec2hex(opts = {}) ⇒ String + + + + + + + + + + + + + +
    +

    Encode an decimal string to a hexadecimal string.

    +
    + +
  • + + +
  • + + + #dec2hex!(opts = {}) ⇒ Object + + + + + + + + + + + + + +
    +

    Encode an decimal string to a hexadecimal string in place as described for #dec2hex.

    +
    +
  • @@ -346,6 +394,102 @@

    Decode the string from base64 in place as described for #from_b64.

    + + + +
  • + + + #from_hex(opts = {}) ⇒ String + + + + + + + + + + + + + +
    +

    Decode a hexadecimal string.

    +
    + +
  • + + +
  • + + + #from_hex!(opts = {}) ⇒ Object + + + + + + + + + + + + + +
    +

    Decode a hexadecimal string in place as described for #from_hex.

    +
    + +
  • + + +
  • + + + #hex2dec(opts = {}) ⇒ String + + + + + + + + + + + + + +
    +

    Encode an hexadecimal string to a decimal string.

    +
    + +
  • + + +
  • + + + #hex2dec!(opts = {}) ⇒ Object + + + + + + + + + + + + + +
    +

    Encode an hexadecimal string to a decimal string in place as described for #hex2dec.

    +
    +
  • @@ -583,7 +727,7 @@

    -

    Calculate the sha1 hash of the string in place as described for #sha1.

    +

    Calculate the sha1 hash of the string in place as described for #sha1.

    @@ -631,7 +775,7 @@

    -

    Calculate the sha2 hash of the string in place as described for #sha2.

    +

    Calculate the sha2 hash of the string in place as described for #sha2.

    @@ -826,6 +970,54 @@

    Encode the string into base64 in place as described for #to_b64.

    + + + +
  • + + + #to_hex(opts = {}) ⇒ String + + + + + + + + + + + + + +
    +

    Encode a string into hexadecimal.

    +
    + +
  • + + +
  • + + + #to_hex!(opts = {}) ⇒ Object + + + + + + + + + + + + + +
    +

    Encode a string into hexadecimal in place as described for #to_hex.

    +
    +
  • @@ -1150,6 +1342,14 @@

     
     
    +69
    +70
    +71
    +72
    +73
    +74
    +75
    +76
     77
     78
     79
    @@ -1163,24 +1363,16 @@ 

    87 88 89 -90 -91 -92 -93 -94 -95 -96 -97 -98

    +90 -
    # File 'lib/ctf_party/base64.rb', line 77
    +      
    # File 'lib/ctf_party/base64.rb', line 69
     
     def b64?(opts = {})
       opts[:mode] ||= :strict
    -  b64 = false
    -  # https://www.rexegg.com/regex-ruby.html
    -  reg1 = %r{\A(?:[a-zA-Z0-9+/]{4})*(?:|(?:[a-zA-Z0-9+/]{3}=)|
    +  b64 = false  # https://www.rexegg.com/regex-ruby.html
    +
    +  reg1 = %r{\A(?:[a-zA-Z0-9+/]{4})*(?:|(?:[a-zA-Z0-9+/]{3}=)|
                 (?:[a-zA-Z0-9+/]{2}==)|(?:[a-zA-Z0-9+/]{1}===))\Z}xn
       reg3 = /\A(?:[a-zA-Z0-9\-_]{4})*(?:|(?:[a-zA-Z0-9\-_]{3}=)|
               (?:[a-zA-Z0-9\-_]{2}==)|(?:[a-zA-Z0-9\-_]{1}===))\Z/xn
    @@ -1204,9 +1396,9 @@ 

    -

    +

    - #flagString + #dec2hex(opts = {}) ⇒ String @@ -1215,13 +1407,79 @@

    -

    Format the current string into the configured flag format. See flag= example.

    +

    Encode an decimal string to a hexadecimal string

    +
    +

    Examples:

    + + +
    '255'.dec2hex # => "ff"
    +'255'.dec2hex({prefix: '0x', case: :upper}) # => "0xFF"
    + +
    +

    Parameters:

    +
      + +
    • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +
      +

      optional parameters

      +
      + +
    • + +
    + + + + +

    Options Hash (opts):

    +
      + +
    • + :prefix + (String) + + + + + —
      +

      Prefix of the output. Default value is a void string. Example of values: 0x, \x.

      +
      + +
    • + +
    • + :case + (Symbol) + + + + + —
      +

      Char case of the ouput. Default value :lower. Other valid value :upper.

      +
      + +
    • + +
    + +

    Returns:

      @@ -1234,7 +1492,7 @@

      -

      the format flag.

      +

      the hexadecimal encoded string

      @@ -1247,9 +1505,133 @@

       
       
      -48
      -49
      -50
      +40
      +41
      +42
      +43
      +44
      +45
      +46
      +47
      +48
      +49
      + + +
      # File 'lib/ctf_party/hex.rb', line 40
      +
      +def dec2hex(opts = {})
      +  opts[:prefix] ||= ''
      +  opts[:case] ||= :lower  # convert
      +
      +  out = to_i.to_s(16)  # char case management
      +
      +  out = out.upcase if opts[:case] == :upper  # adding prefix must be done after case change
      +
      +  return opts[:prefix] + out
      +end
      + + + +

    + +
    +

    + + #dec2hex!(opts = {}) ⇒ Object + + + + + +

    +
    + +

    Encode an decimal string to a hexadecimal string in place as described for #dec2hex.

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    a = '255'
    +a.dec2hex!
    +a # => "ff"
    + +
    + + +
    + + + + +
    +
    +
    +
    +57
    +58
    +59
    +
    +
    # File 'lib/ctf_party/hex.rb', line 57
    +
    +def dec2hex!(opts = {})
    +  replace(dec2hex(opts))
    +end
    +
    +
    + +
    +

    + + #flagString + + + + + +

    +
    + +

    Format the current string into the configured flag format. See flag= example.

    + + +
    +
    +
    + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      the format flag.

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +48
    +49
    +50
     51
     52
     53
    @@ -1524,23 +1906,400 @@ 

     
     
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    +41 +42 +43 +44 +45 +46 +47

    +
    +
    # File 'lib/ctf_party/base64.rb', line 41
    +
    +def from_b64(opts = {})
    +  opts[:mode] ||= :strict
    +  return Base64.strict_decode64(self) if opts[:mode] == :strict ||
    +                                         opts[:mode] == :rfc4648
    +  return Base64.decode64(self) if opts[:mode] == :rfc2045
    +  return Base64.urlsafe_decode64(self) if opts[:mode] == :urlsafe
    +end
    +
    +
    + +
    +

    + + #from_b64!(opts = {}) ⇒ nil + + + + + +

    +
    + +

    Decode the string from base64 in place as described for #from_b64.

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    a = 'SGVsbG8gd29ybGQh' # => "SGVsbG8gd29ybGQh"
    +a.from_b64! # => nil
    +a # => "Hello world!"
    + +
    + +

    Returns:

    +
      + +
    • + + + (nil) + + + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +55
    +56
    +57
    +
    +
    # File 'lib/ctf_party/base64.rb', line 55
    +
    +def from_b64!(opts = {})
    +  replace(from_b64(opts))
    +end
    +
    +
    + +
    +

    + + #from_hex(opts = {}) ⇒ String + + + + + +

    +
    + +

    Decode a hexadecimal string

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    "6e6f72616a".from_hex # => "noraj"
    +"0x6e6f72616a".from_hex(prefix: '0x') # => "noraj"
    +"e6f62716a6".from_hex(nibble: :low) # => "noraj"
    + +
    +

    Parameters:

    +
      + +
    • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +
      +

      optional parameters

      +
      + +
    • + +
    + + + + +

    Options Hash (opts):

    +
      + +
    • + :prefix + (String) + + + + + —
      +

      Prefix of the input. Default value is a void string. Example of values: 0x, \x.

      +
      + +
    • + +
    • + :nibble + (Symbol) + + + + + —
      +

      Display input with high nibble first (:high default) or low nibble first (:low).

      +
      + +
    • + +
    + + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      the hexadecimal decoded string

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +113
    +114
    +115
    +116
    +117
    +118
    +119
    +120
    +121
    +122
    +123
    +
    +
    # File 'lib/ctf_party/hex.rb', line 113
    +
    +def from_hex(opts = {})
    +  opts[:prefix] ||= ''
    +  opts[:nibble] ||= :high  # remove prefix
    +
    +  out = sub(opts[:prefix], '')  # convert
    +
    +  return Array(out).pack('H*') if opts[:nibble] == :high
    +  return Array(out).pack('h*') if opts[:nibble] == :low
    +
    +  raise ArgumentError ':nibble expects :high or :low'
    +end
    +
    +
    + +
    +

    + + #from_hex!(opts = {}) ⇒ Object + + + + + +

    +
    + +

    Decode a hexadecimal string in place as described for #from_hex.

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    a = "6e6f72616a"
    +a.from_hex!
    +a # => "noraj"
    + +
    + + +
    + + + + +
    +
    +
    +
    +131
    +132
    +133
    +
    +
    # File 'lib/ctf_party/hex.rb', line 131
    +
    +def from_hex!(opts = {})
    +  replace(from_hex(opts))
    +end
    +
    +
    + +
    +

    + + #hex2dec(opts = {}) ⇒ String + + + + + +

    +
    + +

    Encode an hexadecimal string to a decimal string

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    'ff'.hex2dec # => "255"
    +'\xf3'.hex2dec(prefix: '\x') # => "243"
    + +
    +

    Parameters:

    +
      + +
    • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +
      +

      optional parameters

      +
      + +
    • + +
    + + + + +

    Options Hash (opts):

    +
      + +
    • + :prefix + (String) + + + + + —
      +

      Prefix of the input. Default value is a void string. Example of values: 0x, \x.

      +
      + +
    • + +
    + + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      the decimal encoded string

      +
      + +
    • + +
    + +
    + + @@ -1548,9 +2307,9 @@

    -

    +

    - #from_b64!(opts = {}) ⇒ nil + #hex2dec!(opts = {}) ⇒ Object @@ -1559,7 +2318,7 @@

    -

    Decode the string from base64 in place as described for #from_b64.

    +

    Encode an hexadecimal string to a decimal string in place as described for #hex2dec.

    @@ -1570,25 +2329,12 @@

    Examples:

    -
    a = 'SGVsbG8gd29ybGQh' # => "SGVsbG8gd29ybGQh"
    -a.from_b64! # => nil
    -a # => "Hello world!"
    +
    a = 'ff'
    +a.hex2dec!
    +a # => => "255"

    -

    Returns:

    -
      - -
    • - - - (nil) - - - -
    • - -

    +
    +
    +
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    -
    # File 'lib/ctf_party/base64.rb', line 45
    -
    -def from_b64(opts = {})
    -  opts[:mode] ||= :strict
    -  return Base64.strict_decode64(self) if opts[:mode] == :strict ||
    -                                         opts[:mode] == :rfc4648
    -  return Base64.decode64(self) if opts[:mode] == :rfc2045
    -  return Base64.urlsafe_decode64(self) if opts[:mode] == :urlsafe
    +      
    # File 'lib/ctf_party/hex.rb', line 12
    +
    +def hex2dec(opts = {})
    +  opts[:prefix] ||= ''  # remove prefix
    +
    +  out = sub(opts[:prefix], '')  # convert
    +
    +  return out.hex.to_s
     end
    @@ -1596,23 +2342,15 @@

     
     
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    +26 +27 +28

    @@ -1803,12 +2541,12 @@

     
     
    -102
    -103
    -104
    +104 +105 +106

    + +
    -
    # File 'lib/ctf_party/base64.rb', line 59
    +      
    # File 'lib/ctf_party/hex.rb', line 26
     
    -def from_b64!(opts = {})
    -  opts[:mode] ||= :strict
    -  replace(from_b64) if opts[:mode] == :strict ||
    -                       opts[:mode] == :rfc4648
    -  replace(from_b64(mode: :rfc2045)) if opts[:mode] == :rfc2045
    -  replace(from_b64(mode: :urlsafe)) if opts[:mode] == :urlsafe
    +def hex2dec!(opts = {})
    +  replace(hex2dec(opts))
     end
    -
    # File 'lib/ctf_party/digest.rb', line 102
    +      
    # File 'lib/ctf_party/digest.rb', line 104
     
     def rmd160
       Digest::RMD160.hexdigest self
    @@ -1854,12 +2592,12 @@ 

     
     
    -112
    -113
    -114
    +114 +115 +116

    -
    # File 'lib/ctf_party/digest.rb', line 112
    +      
    # File 'lib/ctf_party/digest.rb', line 114
     
     def rmd160!
       replace(rmd160)
    @@ -2239,7 +2977,10 @@ 

    -

    Calculate the sha1 hash of the string in place as described for #sha1.

    +

    Calculate the sha1 hash of the string in place as described for

    + +
    {String#sha1}.
    +
    @@ -2263,12 +3004,12 @@

     
     
    -39
     40
    -41
    +41 +42

    -
    # File 'lib/ctf_party/digest.rb', line 39
    +      
    # File 'lib/ctf_party/digest.rb', line 40
     
     def sha1!
       replace(sha1)
    @@ -2382,13 +3123,13 @@ 

     
     
    -53
     54
     55
    -56
    +56 +57

    -
    # File 'lib/ctf_party/digest.rb', line 53
    +      
    # File 'lib/ctf_party/digest.rb', line 54
     
     def sha2(opts = {})
       opts[:bitlen] ||= 256
    @@ -2411,7 +3152,10 @@ 

    -

    Calculate the sha2 hash of the string in place as described for #sha2.

    +

    Calculate the sha2 hash of the string in place as described for

    + +
    {String#sha2}.
    +
    @@ -2435,12 +3179,12 @@

     
     
    -63
    -64
    -65
    +65 +66 +67

    -
    # File 'lib/ctf_party/digest.rb', line 63
    +      
    # File 'lib/ctf_party/digest.rb', line 65
     
     def sha2!(opts = {})
       replace(sha2(opts))
    @@ -2476,12 +3220,12 @@ 

     
     
    -68
    -69
    -70
    +70 +71 +72

    -
    # File 'lib/ctf_party/digest.rb', line 68
    +      
    # File 'lib/ctf_party/digest.rb', line 70
     
     def sha2_256
       sha2
    @@ -2517,12 +3261,12 @@ 

     
     
    -73
    -74
    -75
    +75 +76 +77

    -
    # File 'lib/ctf_party/digest.rb', line 73
    +      
    # File 'lib/ctf_party/digest.rb', line 75
     
     def sha2_256!
       replace(sha2)
    @@ -2558,12 +3302,12 @@ 

     
     
    -78
    -79
    -80
    +80 +81 +82

    -
    # File 'lib/ctf_party/digest.rb', line 78
    +      
    # File 'lib/ctf_party/digest.rb', line 80
     
     def sha2_384
       sha2(bitlen: 384)
    @@ -2599,12 +3343,12 @@ 

     
     
    -83
    -84
    -85
    +85 +86 +87

    -
    # File 'lib/ctf_party/digest.rb', line 83
    +      
    # File 'lib/ctf_party/digest.rb', line 85
     
     def sha2_384!
       replace(sha2(bitlen: 384))
    @@ -2640,12 +3384,12 @@ 

     
     
    -88
    -89
    -90
    +90 +91 +92

    -
    # File 'lib/ctf_party/digest.rb', line 88
    +      
    # File 'lib/ctf_party/digest.rb', line 90
     
     def sha2_512
       sha2(bitlen: 512)
    @@ -2681,12 +3425,12 @@ 

     
     
    -93
    -94
    -95
    +95 +96 +97

    -
    # File 'lib/ctf_party/digest.rb', line 93
    +      
    # File 'lib/ctf_party/digest.rb', line 95
     
     def sha2_512!
       replace(sha2(bitlen: 512))
    @@ -2873,21 +3617,230 @@ 

    29 30 -31 -32 -33 -34 -35

    +31
    # File 'lib/ctf_party/base64.rb', line 29
     
     def to_b64!(opts = {})
    -  opts[:mode] ||= :strict
    -  replace(to_b64) if opts[:mode] == :strict ||
    -                     opts[:mode] == :rfc4648
    -  replace(to_b64(mode: :rfc2045)) if opts[:mode] == :rfc2045
    -  replace(to_b64(mode: :urlsafe)) if opts[:mode] == :urlsafe
    +  replace(to_b64(opts))
    +end
    +
    +
    + +
    +

    + + #to_hex(opts = {}) ⇒ String + + + + + +

    +
    + +

    Encode a string into hexadecimal

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    'noraj'.to_hex # => "6e6f72616a"
    +'noraj'.to_hex(prefix: '0x') # => "0x6e6f72616a"
    +'noraj'.to_hex(case: :upper) # => "6E6F72616A"
    +'noraj'.to_hex(nibble: :low) # => "e6f62716a6"
    + +
    +

    Parameters:

    +
      + +
    • + + opts + + + (Hash) + + + (defaults to: {}) + + + — +
      +

      optional parameters

      +
      + +
    • + +
    + + + + +

    Options Hash (opts):

    +
      + +
    • + :prefix + (String) + + + + + —
      +

      Prefix of the output. Default value is a void string. Example of values: 0x, \x.

      +
      + +
    • + +
    • + :case + (Symbol) + + + + + —
      +

      Char case of the ouput. Default value :lower. Other valid value :upper.

      +
      + +
    • + +
    • + :nibble + (Symbol) + + + + + —
      +

      Display output with high nibble first (:high default) or low nibble first (:low).

      +
      + +
    • + +
    + + +

    Returns:

    +
      + +
    • + + + (String) + + + + — +
      +

      the hexadecimal encoded string

      +
      + +
    • + +
    + +
    + + + + +
    +
    +
    +
    +75
    +76
    +77
    +78
    +79
    +80
    +81
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    +89
    +90
    +
    +
    # File 'lib/ctf_party/hex.rb', line 75
    +
    +def to_hex(opts = {})
    +  opts[:prefix] ||= ''
    +  opts[:case] ||= :lower
    +  opts[:nibble] ||= :high  # convert
    +
    +  out = ''
    +  if opts[:nibble] == :high
    +    out = unpack1('H*')
    +  elsif opts[:nibble] == :low
    +    out = unpack1('h*')
    +  end  # char case management
    +
    +  out = out.upcase if opts[:case] == :upper  # adding prefix must be done after case change
    +
    +  return opts[:prefix] + out
    +end
    +
    +
    + +
    +

    + + #to_hex!(opts = {}) ⇒ Object + + + + + +

    +
    + +

    Encode a string into hexadecimal in place as described for #to_hex.

    + + +
    +
    +
    + +
    +

    Examples:

    + + +
    a = 'noraj'
    +a.to_hex!
    +a # => "6e6f72616a"
    + +
    + + +
    + + + @@ -2899,9 +3852,9 @@

    diff --git a/docs/yard/Version.html b/docs/yard/Version.html index 0ced202..fd15e7b 100644 --- a/docs/yard/Version.html +++ b/docs/yard/Version.html @@ -6,15 +6,15 @@ Module: Version - — Documentation by YARD 0.9.20 + — Documentation by YARD 0.9.23 - + - + - @@ -95,7 +95,7 @@

    VERSION =
    -
    '1.0.0'
    +
    '1.1.0'
    @@ -111,9 +111,9 @@

    diff --git a/docs/yard/_index.html b/docs/yard/_index.html index e888fb5..d867d7d 100644 --- a/docs/yard/_index.html +++ b/docs/yard/_index.html @@ -4,15 +4,15 @@ - Documentation by YARD 0.9.20 + Documentation by YARD 0.9.23 - + - + - @@ -52,7 +52,7 @@
    -

    Documentation by YARD 0.9.20

    +

    Documentation by YARD 0.9.23

    Alphabetic Index

    @@ -113,9 +113,9 @@

    Namespace Listing A-Z

    diff --git a/docs/yard/class_list.html b/docs/yard/class_list.html index 26bcecd..559a28c 100644 --- a/docs/yard/class_list.html +++ b/docs/yard/class_list.html @@ -4,9 +4,9 @@ - + - + diff --git a/docs/yard/css/style.css b/docs/yard/css/style.css index 0bf7e2c..62f4349 100644 --- a/docs/yard/css/style.css +++ b/docs/yard/css/style.css @@ -422,8 +422,8 @@ li.r2 { background: #fafafa; } #toc ol { padding-left: 1.8em; } #toc li { font-size: 1.1em; line-height: 1.7em; } #toc > ol > li { font-size: 1.1em; font-weight: bold; } -#toc ol > ol { font-size: 0.9em; } -#toc ol ol > ol { padding-left: 2.3em; } +#toc ol > li > ol { font-size: 0.9em; } +#toc ol ol > li > ol { padding-left: 2.3em; } #toc ol + li { margin-top: 0.3em; } #toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } #toc.hidden:hover { background: #fafafa; } diff --git a/docs/yard/file.LICENSE.html b/docs/yard/file.LICENSE.html index ad0519a..922e1cb 100644 --- a/docs/yard/file.LICENSE.html +++ b/docs/yard/file.LICENSE.html @@ -6,15 +6,15 @@ File: LICENSE - — Documentation by YARD 0.9.20 + — Documentation by YARD 0.9.23 - + - + - @@ -60,9 +60,9 @@
    The MIT License (MIT)

    Copyright (c) 2019 Alexandre ZANNI

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    diff --git a/docs/yard/file.README.html b/docs/yard/file.README.html index 55ba882..706eb83 100644 --- a/docs/yard/file.README.html +++ b/docs/yard/file.README.html @@ -6,15 +6,15 @@ File: README - — Documentation by YARD 0.9.20 + — Documentation by YARD 0.9.23 - + - + - @@ -66,7 +66,7 @@ GitHub license Rawsec's CyberSecurity Inventory

    -

    Packaging status

    +

    Packaging status

    @@ -77,7 +77,7 @@

    What it is

    by patching the String class to add a short syntax of usual code patterns. The philosophy is also to keep the library to be pure ruby (no dependencies) and not to re-implement what another library is already doing well -(eg.xorcist for xor).

    +(eg. xorcist for xor).

    For example instead of writting:

    @@ -102,6 +102,7 @@

    Features

  • digest: md5, md5!, sha1, sha1!, etc.
  • flag: flag, flag!, flag? (apply/check a flag format)
  • rot: rot, rot!, rot13, rot13!
  • +
  • hex: hex2dec, dec2hex, to_hex, from_hex and bang versions
  • References

    @@ -114,9 +115,9 @@

    Author

    diff --git a/docs/yard/file_list.html b/docs/yard/file_list.html index 61ad926..811c3fd 100644 --- a/docs/yard/file_list.html +++ b/docs/yard/file_list.html @@ -4,9 +4,9 @@ - + - + diff --git a/docs/yard/frames.html b/docs/yard/frames.html index 60223fe..0704fe5 100644 --- a/docs/yard/frames.html +++ b/docs/yard/frames.html @@ -2,9 +2,9 @@ - Documentation by YARD 0.9.20 + Documentation by YARD 0.9.23 - @@ -66,7 +66,7 @@ GitHub licenseRawsec's CyberSecurity Inventory

    -

    Packaging status

    +

    Packaging status

    @@ -77,7 +77,7 @@

    What it is

    by patching the String class to add a short syntax of usual code patterns. The philosophy is also to keep the library to be pure ruby (no dependencies) and not to re-implement what another library is already doing well -(eg.xorcist for xor).

    +(eg. xorcist for xor).

    For example instead of writting:

    @@ -102,6 +102,7 @@

    Features

  • digest: md5, md5!, sha1, sha1!, etc.
  • flag: flag, flag!, flag? (apply/check a flag format)
  • rot: rot, rot!, rot13, rot13!
  • +
  • hex: hex2dec, dec2hex, to_hex, from_hex and bang versions
  • References

    @@ -114,9 +115,9 @@

    Author

    diff --git a/docs/yard/js/app.js b/docs/yard/js/app.js index 368f44a..8d067fe 100644 --- a/docs/yard/js/app.js +++ b/docs/yard/js/app.js @@ -171,6 +171,7 @@ function generateTOC() { var counter = 0; var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; var i; + var curli; if ($('#filecontents h1').length > 1) tags.unshift('h1'); for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } var lastTag = parseInt(tags[0][1], 10); @@ -190,15 +191,25 @@ function generateTOC() { } if (thisTag > lastTag) { for (i = 0; i < thisTag - lastTag; i++) { - var tmp = $('
      '); toc.append(tmp); toc = tmp; + if ( typeof(curli) == "undefined" ) { + curli = $('
    1. '); + toc.append(curli); + } + toc = $('
        '); + curli.append(toc); + curli = undefined; } } if (thisTag < lastTag) { - for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent(); + for (i = 0; i < lastTag - thisTag; i++) { + toc = toc.parent(); + toc = toc.parent(); + } } var title = $(this).attr('toc-title'); if (typeof(title) == "undefined") title = $(this).text(); - toc.append('
      1. ' + title + '
      2. '); + curli =$('
      3. ' + title + '
      4. '); + toc.append(curli); lastTag = thisTag; }); if (!show) return; diff --git a/docs/yard/method_list.html b/docs/yard/method_list.html index 1890b71..77d4c51 100644 --- a/docs/yard/method_list.html +++ b/docs/yard/method_list.html @@ -4,9 +4,9 @@ - + - + @@ -52,6 +52,22 @@

        Method List

        +
      5. +
        + #dec2hex + String +
        +
      6. + + +
      7. +
        + #dec2hex! + String +
        +
      8. + +
      9. flag @@ -108,6 +124,38 @@

        Method List

      10. +
      11. +
        + #from_hex + String +
        +
      12. + + +
      13. +
        + #from_hex! + String +
        +
      14. + + +
      15. +
        + #hex2dec + String +
        +
      16. + + +
      17. +
        + #hex2dec! + String +
        +
      18. + +
      19. #md5 @@ -268,6 +316,22 @@

        Method List

      20. +
      21. +
        + #to_hex + String +
        +
      22. + + +
      23. +
        + #to_hex! + String +
        +
      24. + + diff --git a/docs/yard/top-level-namespace.html b/docs/yard/top-level-namespace.html index 12437d4..1b2ca8e 100644 --- a/docs/yard/top-level-namespace.html +++ b/docs/yard/top-level-namespace.html @@ -6,15 +6,15 @@ Top Level Namespace - — Documentation by YARD 0.9.20 + — Documentation by YARD 0.9.23 - + - + - @@ -102,9 +102,9 @@

        Defined Under Namespace

        diff --git a/lib/ctf_party.rb b/lib/ctf_party.rb index def7950..f16bb25 100644 --- a/lib/ctf_party.rb +++ b/lib/ctf_party.rb @@ -5,3 +5,4 @@ require 'ctf_party/rot' require 'ctf_party/digest' require 'ctf_party/flag' +require 'ctf_party/hex' diff --git a/lib/ctf_party/base64.rb b/lib/ctf_party/base64.rb index 4f012bc..fdfd32d 100644 --- a/lib/ctf_party/base64.rb +++ b/lib/ctf_party/base64.rb @@ -27,11 +27,7 @@ def to_b64(opts = {}) # myStr.to_b64! # => nil # myStr # => "UnVieQ==" def to_b64!(opts = {}) - opts[:mode] ||= :strict - replace(to_b64) if opts[:mode] == :strict || - opts[:mode] == :rfc4648 - replace(to_b64(mode: :rfc2045)) if opts[:mode] == :rfc2045 - replace(to_b64(mode: :urlsafe)) if opts[:mode] == :urlsafe + replace(to_b64(opts)) end # Decode the string from base64 @@ -57,11 +53,7 @@ def from_b64(opts = {}) # a.from_b64! # => nil # a # => "Hello world!" def from_b64!(opts = {}) - opts[:mode] ||= :strict - replace(from_b64) if opts[:mode] == :strict || - opts[:mode] == :rfc4648 - replace(from_b64(mode: :rfc2045)) if opts[:mode] == :rfc2045 - replace(from_b64(mode: :urlsafe)) if opts[:mode] == :urlsafe + replace(from_b64(opts)) end # Is the string encoded in base64? diff --git a/lib/ctf_party/digest.rb b/lib/ctf_party/digest.rb index 6f15bea..28ac618 100644 --- a/lib/ctf_party/digest.rb +++ b/lib/ctf_party/digest.rb @@ -13,7 +13,7 @@ def md5 Digest::MD5.hexdigest self end - # Calculate the md5 hash of the string in place as described for {#md5}. + # Calculate the md5 hash of the string in place as described for {String#md5}. # @example # a = '\o/' # => "\\o/" # a.md5! # => "881419964e480e66162da521ccc25ebf" @@ -31,7 +31,8 @@ def sha1 Digest::SHA1.hexdigest self end - # Calculate the sha1 hash of the string in place as described for {#sha1}. + # Calculate the sha1 hash of the string in place as described for + # {String#sha1}. # @example # bob = 'alice' # => "alice" # bob.sha1! # => "522b276a356bdf39013dfabea2cd43e141ecc9e8" @@ -55,7 +56,8 @@ def sha2(opts = {}) Digest::SHA2.new(opts[:bitlen]).hexdigest self end - # Calculate the sha2 hash of the string in place as described for {#sha2}. + # Calculate the sha2 hash of the string in place as described for + # {String#sha2}. # @example # th = 'try harder' # => "try harder" # th.sha2!(bitlen: 384) # => "bb7f60b9562a19c3a83c23791440af11591c42ede9..." @@ -64,32 +66,32 @@ def sha2!(opts = {}) replace(sha2(opts)) end - # Alias for {#sha2} with default value ( +sha2(bitlen: 256)+ ). + # Alias for {String#sha2} with default value ( +sha2(bitlen: 256)+ ). def sha2_256 sha2 end - # Alias for {#sha2!} with default value ( +sha2!(bitlen: 256)+ ). + # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 256)+ ). def sha2_256! replace(sha2) end - # Alias for {#sha2} with default value ( +sha2(bitlen: 384)+ ). + # Alias for {String#sha2} with default value ( +sha2(bitlen: 384)+ ). def sha2_384 sha2(bitlen: 384) end - # Alias for {#sha2!} with default value ( +sha2!(bitlen: 384)+ ). + # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 384)+ ). def sha2_384! replace(sha2(bitlen: 384)) end - # Alias for {#sha2} with default value ( +sha2(bitlen: 512)+ ). + # Alias for {String#sha2} with default value ( +sha2(bitlen: 512)+ ). def sha2_512 sha2(bitlen: 512) end - # Alias for {#sha2!} with default value ( +sha2!(bitlen: 512)+ ). + # Alias for {String#sha2!} with default value ( +sha2!(bitlen: 512)+ ). def sha2_512! replace(sha2(bitlen: 512)) end @@ -104,7 +106,7 @@ def rmd160 end # Calculate the RIPEMD-160 hash of the string in place as described for - # {#rmd160}. + # {String#rmd160}. # @example # pl = 'payload' # => "payload" # pl.rmd160! # => "3c6255c112d409dafdb84d5b0edba98dfd27b44f" diff --git a/lib/ctf_party/flag.rb b/lib/ctf_party/flag.rb index 17712aa..e9c034c 100644 --- a/lib/ctf_party/flag.rb +++ b/lib/ctf_party/flag.rb @@ -72,7 +72,7 @@ def flag end # Format the current string into the configured flag format in place as - # described for {#flag}. + # described for {String#flag}. def flag! replace(flag) end diff --git a/lib/ctf_party/hex.rb b/lib/ctf_party/hex.rb new file mode 100644 index 0000000..b875640 --- /dev/null +++ b/lib/ctf_party/hex.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +class String + # Encode an hexadecimal string to a decimal string + # @param opts [Hash] optional parameters + # @option opts [String] :prefix Prefix of the input. Default value is a void + # string. Example of values: +0x+, +\x+. + # @return [String] the decimal encoded string + # @example + # 'ff'.hex2dec # => "255" + # '\xf3'.hex2dec(prefix: '\x') # => "243" + def hex2dec(opts = {}) + opts[:prefix] ||= '' + # remove prefix + out = sub(opts[:prefix], '') + # convert + return out.hex.to_s + end + + # Encode an hexadecimal string to a decimal string in place as described + # for {String#hex2dec}. + # @example + # a = 'ff' + # a.hex2dec! + # a # => => "255" + def hex2dec!(opts = {}) + replace(hex2dec(opts)) + end + + # Encode an decimal string to a hexadecimal string + # @param opts [Hash] optional parameters + # @option opts [String] :prefix Prefix of the output. Default value is a void + # string. Example of values: +0x+, +\x+. + # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+. + # Other valid value +:upper+. + # @return [String] the hexadecimal encoded string + # @example + # '255'.dec2hex # => "ff" + # '255'.dec2hex({prefix: '0x', case: :upper}) # => "0xFF" + def dec2hex(opts = {}) + opts[:prefix] ||= '' + opts[:case] ||= :lower + # convert + out = to_i.to_s(16) + # char case management + out = out.upcase if opts[:case] == :upper + # adding prefix must be done after case change + return opts[:prefix] + out + end + + # Encode an decimal string to a hexadecimal string in place as described + # for {String#dec2hex}. + # @example + # a = '255' + # a.dec2hex! + # a # => "ff" + def dec2hex!(opts = {}) + replace(dec2hex(opts)) + end + + # Encode a string into hexadecimal + # @param opts [Hash] optional parameters + # @option opts [String] :prefix Prefix of the output. Default value is a void + # string. Example of values: +0x+, +\x+. + # @option opts [Symbol] :case Char case of the ouput. Default value +:lower+. + # Other valid value +:upper+. + # @option opts [Symbol] :nibble Display output with high nibble first + # (+:high+ default) or low nibble first (+:low+). + # @return [String] the hexadecimal encoded string + # @example + # 'noraj'.to_hex # => "6e6f72616a" + # 'noraj'.to_hex(prefix: '0x') # => "0x6e6f72616a" + # 'noraj'.to_hex(case: :upper) # => "6E6F72616A" + # 'noraj'.to_hex(nibble: :low) # => "e6f62716a6" + def to_hex(opts = {}) + opts[:prefix] ||= '' + opts[:case] ||= :lower + opts[:nibble] ||= :high + # convert + out = '' + if opts[:nibble] == :high + out = unpack1('H*') + elsif opts[:nibble] == :low + out = unpack1('h*') + end + # char case management + out = out.upcase if opts[:case] == :upper + # adding prefix must be done after case change + return opts[:prefix] + out + end + + # Encode a string into hexadecimal in place as described + # for {String#to_hex}. + # @example + # a = 'noraj' + # a.to_hex! + # a # => "6e6f72616a" + def to_hex!(opts = {}) + replace(to_hex(opts)) + end + + # Decode a hexadecimal string + # @param opts [Hash] optional parameters + # @option opts [String] :prefix Prefix of the input. Default value is a void + # string. Example of values: +0x+, +\x+. + # @option opts [Symbol] :nibble Display input with high nibble first + # (+:high+ default) or low nibble first (+:low+). + # @return [String] the hexadecimal decoded string + # @example + # "6e6f72616a".from_hex # => "noraj" + # "0x6e6f72616a".from_hex(prefix: '0x') # => "noraj" + # "e6f62716a6".from_hex(nibble: :low) # => "noraj" + def from_hex(opts = {}) + opts[:prefix] ||= '' + opts[:nibble] ||= :high + # remove prefix + out = sub(opts[:prefix], '') + # convert + return Array(out).pack('H*') if opts[:nibble] == :high + return Array(out).pack('h*') if opts[:nibble] == :low + + raise ArgumentError ':nibble expects :high or :low' + end + + # Decode a hexadecimal string in place as described + # for {String#from_hex}. + # @example + # a = "6e6f72616a" + # a.from_hex! + # a # => "noraj" + def from_hex!(opts = {}) + replace(from_hex(opts)) + end +end diff --git a/lib/ctf_party/rot.rb b/lib/ctf_party/rot.rb index bcd1998..27474f2 100644 --- a/lib/ctf_party/rot.rb +++ b/lib/ctf_party/rot.rb @@ -35,12 +35,12 @@ def rot!(opts = {}) replace(rot(opts)) end - # Alias for {#rot} with default value ( +rot(shift: 13)+ ). + # Alias for {String#rot} with default value ( +rot(shift: 13)+ ). def rot13 rot end - # Alias for {#rot!} with default value ( +rot!(shift: 13)+ ). + # Alias for {String#rot!} with default value ( +rot!(shift: 13)+ ). def rot13! rot! end diff --git a/lib/ctf_party/version.rb b/lib/ctf_party/version.rb index f9853f2..53e5582 100644 --- a/lib/ctf_party/version.rb +++ b/lib/ctf_party/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Version - VERSION = '1.0.0' + VERSION = '1.1.0' end diff --git a/test/test_string.rb b/test/test_string.rb index 340d271..8aec43d 100644 --- a/test/test_string.rb +++ b/test/test_string.rb @@ -131,4 +131,43 @@ def test_rot_rot13 def test_rot_rot13! # skip end + + def test_hex_hex2dec + assert_equal('255', 'ff'.hex2dec) + assert_equal('243', '\xf3'.hex2dec(prefix: '\x')) + end + + def test_hex_hex2dec! + # skip + end + + def test_hex_dec2hex + assert_equal('ff', '255'.dec2hex) + assert_equal('0xFF', '255'.dec2hex(prefix: '0x', case: :upper)) + end + + def test_hex_dec2hex! + # skip + end + + def test_hex_to_hex + assert_equal('6e6f72616a', 'noraj'.to_hex) + assert_equal('0x6e6f72616a', 'noraj'.to_hex(prefix: '0x')) + assert_equal('6E6F72616A', 'noraj'.to_hex(case: :upper)) + assert_equal('e6f62716a6', 'noraj'.to_hex(nibble: :low)) + end + + def test_hex_to_hex! + # skip + end + + def test_hex_from_hex + assert_equal('noraj', '6e6f72616a'.from_hex) + assert_equal('noraj', '0x6e6f72616a'.from_hex(prefix: '0x')) + assert_equal('noraj', 'e6f62716a6'.from_hex(nibble: :low)) + end + + def test_hex_from_hex! + # skip + end end
    +
    +
    +
    +98
    +99
    +100
    +
    +
    # File 'lib/ctf_party/hex.rb', line 98
    +
    +def to_hex!(opts = {})
    +  replace(to_hex(opts))
     end