Class: Obfuscator::Expression Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/number_obfuscator/expression.rb,
lib/number_obfuscator/expression.rb

Overview

This class is abstract.

Base class for all the obfuscation expressions we can generate.

Each subclass must, at class initialization time, register itself by calling self.addType, otherwise it won't get used! Also, all subclasses must implement #to_s and #to_tex and the class method Expression.make.

Direct Known Subclasses

BinaryExpression, Number, SquareRoot

Constant Summary collapse

@@types =
[]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.addType(c, weight = 1) ⇒ Object

Every expression subclass must register itself with the factory by calling

this method.

“Weight” influences the likelyhood that a type will be randomly chosen; a large weight means that expressions of that type will show up more often in the output.


20
21
22
# File 'lib/number_obfuscator/expression.rb', line 20

def self.addType(c, weight = 1)
  weight.times { @@types.push(c) }
end

.make(n, depth) ⇒ Expression?

This method is abstract.

Override this to create a new sub-expression.

Each subclass of Expression must provide a class-level 'make' method which returns an object of that subclass, representing n.

In order to create its own sub-expressions, it calls 'make' again with a depth value of “depth - 1”. (Subclasses do not need to worry about the case that depth == 0; makeExpression will take care of that.)

Subclass implementations are allowed to return 'nil' if they are unable to provide an expression for the given n.

Parameters:

  • n (Integer)

    The number to obfuscate.

  • depth (Integer)

    Desired depth of the expression. Will be >= 1.

Returns:

  • (Expression, nil)

    New Expression, or nil if not possible to create one.


53
54
55
# File 'lib/number_obfuscator/expression.rb', line 53

def Expression.make(n, depth)
  raise "Subclass must provide its own 'make'!"
end

.makeExpression(n, depth) ⇒ Expression

Returns a new, randomly generated expression tree for a given number.

Parameters:

  • n (Integer)

    The number to be obfuscated.

  • depth (Integer)

    Desired depth (complexity) of the expression.

Returns:


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/number_obfuscator/expression.rb', line 58

def Expression.makeExpression(n, depth)
  if (depth <= 0)
    Number.new(n)
  else
    expr = nil
    attempts = 1
    while expr.nil? && attempts < 10
      candidates = @@types.select { |t| t.canDo(n) }
type = candidates[rand(candidates.size)]
      expr = type.make(n, depth)
      attempts += 1
    end
    expr || Number.new(n) # Safety guard for hard-to obfuscate numbers..
  end
end

Instance Method Details

#to_sObject

This method is abstract.

Each subclass of Expression must override to_s to return a valid Ruby expression, which can be parsed with 'eval' to get the original number back.


27
28
29
# File 'lib/number_obfuscator/expression.rb', line 27

def to_s
  raise "Subclass must override to_s!"
end

#to_texObject

This method is abstract.

Each subclass of Expression must override to_s to return a valid TeX expression, such as '3\cdot9'.


33
34
35
# File 'lib/number_obfuscator/expression.rb', line 33

def to_tex
  raise "Subclass must override to_tex!"
end