class FixedLengthEncoder::Encoder
Public Class Methods
new(alphabet, encode_map, decode_map)
click to toggle source
# File lib/fixed_length_encoder.rb, line 34 def initialize(alphabet, encode_map, decode_map) @alphabet = alphabet @base = alphabet.length @encode_map = encode_map @decode_map = decode_map end
Public Instance Methods
array_to_integer(message)
click to toggle source
# File lib/fixed_length_encoder.rb, line 106 def array_to_integer(message) value = 0 message.reverse.each { |digit| value = (value * @base) + digit } value end
decode(message)
click to toggle source
# File lib/fixed_length_encoder.rb, line 56 def decode(message) raise ArgumentError, 'Cannot decode a non-string.' unless message.is_a?(String) self.setup(message.length) value = self.string_to_integer(message) value = self.scramble_value(value, -1) self.offset(value, -1) end
encode(value, message_length)
click to toggle source
# File lib/fixed_length_encoder.rb, line 46 def encode(value, message_length) raise ArgumentError, 'Cannot encode a non-integer' unless value.is_a?(Integer) raise ArgumentError, 'Cannot encode negative values' if value < 0 self.setup(message_length) raise ArgumentError, "Cannot encode #{value} in #{@message_length} characters" if value >= @max_value value = self.offset(value, +1) value = self.scramble_value(value, +1) string = self.integer_to_string(value) end
integer_to_array(value)
click to toggle source
# File lib/fixed_length_encoder.rb, line 96 def integer_to_array(value) message = [] while (value > 0 || message.length < @message_length) remainder = value % @base message.push remainder value /= @base end message end
integer_to_string(value)
click to toggle source
# File lib/fixed_length_encoder.rb, line 90 def integer_to_string(value) message = integer_to_array(value) message = message.map { |value| @alphabet[value] } message.join end
map_array(message, map, direction)
click to toggle source
# File lib/fixed_length_encoder.rb, line 76 def map_array(message, map, direction) indexes = (0..@message_length).to_a.map { |i| i % @message_length } indexes = indexes.reverse if direction < 0 (0...@message_length).each do |index| low_index = indexes[index] high_index = indexes[index + 1] map_index = message[high_index] * @base + message[low_index] map_value = map[map_index] message[low_index] = map_value / @base message[high_index] = map_value % @base end message end
offset(value, direction)
click to toggle source
# File lib/fixed_length_encoder.rb, line 64 def offset(value, direction) offset = (@max_value/2).floor (value + direction * offset) % @max_value end
scramble_value(value, direction)
click to toggle source
# File lib/fixed_length_encoder.rb, line 69 def scramble_value(value, direction) message = integer_to_array(value) message = map_array(message, @encode_map, direction) if direction > 0 message = map_array(message, @decode_map, direction) if direction < 0 array_to_integer(message) end
setup(message_length)
click to toggle source
# File lib/fixed_length_encoder.rb, line 41 def setup(message_length) @message_length = message_length @max_value = (@alphabet.length)**message_length end
string_to_integer(message)
click to toggle source
# File lib/fixed_length_encoder.rb, line 112 def string_to_integer(message) value = 0 message.reverse.split('').map do |digit| index = @alphabet.index(digit) raise ArgumentError, 'Cannot decode an invalid character (' + digit + ')' if index.nil? value = (value * @base) + index end value end