Class: Obfuscator::Multilang

Inherits:
Object
  • Object
show all
Includes:
Constants, Internal::RNG
Defined in:
lib/obfuscator/multilang.rb

Overview

A class responsible for obfuscating text in Russian and English languages.

This class provides various modes for obfuscating text while preserving the original text structure, whitespace, punctuation, and capitalization. The obfuscation can be performed in several modes and optionally naturalized to produce more readable output.

Available modes:

  • MODE_DIRECT (default): Preserves language, replacing words with same-language random words

  • MODE_ENG_TO_ENG: Only obfuscates English words, leaves Russian untouched

  • MODE_RUS_TO_RUS: Only obfuscates Russian words, leaves English untouched

  • MODE_SWAPPED: Swaps languages (English→Russian and Russian→English)

  • MODE_MIXED: Generates words containing both English and Russian characters

Examples:

Basic usage

obfuscator = Multilang.new
obfuscator.obfuscate("Hello world!") # => "Kites mefal!"

Using swapped mode with naturalization

obfuscator = Multilang.new(mode: :swapped, naturalize: true)
obfuscator.obfuscate("Hello мир!") # => "Привет world!"

Raises:

  • (InputError)

    If input doesn’t respond to :to_s

  • (EncodingError)

    If input has invalid encoding

  • (Error)

    If obfuscation fails for any other reason

Constant Summary collapse

MODE_DIRECT =

1:1 obfuscation, the default

:direct
MODE_ENG_TO_ENG =

eng/rus → eng/rus untouched

:eng_to_eng
MODE_RUS_TO_RUS =

eng/rus → eng untouched/rus

:rus_to_rus
MODE_SWAPPED =

eng→rus and rus→eng

:swapped
MODE_MIXED =

eng/rus → eng+rus mix just for fun

:mixed

Constants included from Constants

Constants::ENGLISH_CONSONANTS, Constants::ENGLISH_ENDINGS, Constants::ENGLISH_VOWELS, Constants::IMPOSSIBLE_COMBINATIONS, Constants::RUSSIAN_CONSONANTS, Constants::RUSSIAN_ENDINGS, Constants::RUSSIAN_VOWELS

Instance Method Summary collapse

Constructor Details

#initialize(mode: MODE_DIRECT, seed: nil, naturalize: false) ⇒ Multilang

Returns a new instance of Multilang.



46
47
48
49
50
51
# File 'lib/obfuscator/multilang.rb', line 46

def initialize(mode: MODE_DIRECT, seed: nil, naturalize: false)
  @mode = mode
  @seed = seed # Store the seed
  setup_rng(seed)
  @naturalizer = Naturalizer.new(seed) if naturalize
end

Instance Method Details

#obfuscate(input) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/obfuscator/multilang.rb', line 53

def obfuscate(input)
  # Reset RNG state before each obfuscation if seed was provided
  setup_rng(@seed) if @seed

  raise InputError, 'Input must respond to :to_s' unless input.respond_to?(:to_s)
  return input if input.nil? || input.is_a?(Numeric)

  text = input.to_s

  # Ensure UTF-8 encoding
  begin
    text = text.encode('UTF-8') unless text.encoding == Encoding::UTF_8
  rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError => e
    raise EncodingError, "Encoding error: #{e.message}"
  end

  # Split preserving all whitespace and punctuation
  begin
    tokens = text.split(/(\s+|[[:punct:]])/)
    tokens.map do |token|
      if token.match?(/\s+|[[:punct:]]/)
        token # Preserve whitespace and punctuation
      else
        process_word(token)
      end
    end.join
  rescue ArgumentError => e
    raise EncodingError, "Encoding error: #{e.message}" if e.message.include?('invalid byte sequence')

    raise Error, "Obfuscation error: #{e.message}"
  rescue StandardError => e
    raise Error, "Obfuscation error: #{e.message}"
  end
rescue NoMethodError => e
  raise InputError, "Input must be a Ruby object with basic methods: #{e.message}"
end