class RadixEncoding::Encoding

Attributes

alphabet[R]
lower_bound[R]
padding[R]
prefix[R]
radix[R]
upper_bound[R]

Public Class Methods

new(alphabet:, radix:, padding: nil, prefix: nil) click to toggle source
# File lib/radix_encoding/encoding.rb, line 20
def initialize(alphabet:, radix:, padding: nil, prefix: nil)
  @alphabet = alphabet
  @padding = padding
  @prefix = prefix
  @radix = radix

  validate!
end

Public Instance Methods

bytes_for(bits) click to toggle source
# File lib/radix_encoding/encoding/bits.rb, line 24
def bytes_for(bits)
  bits.each_slice(8).map do |byte_bits|
    byte_bits.join.to_i(2)
  end
end
decode(data) click to toggle source
# File lib/radix_encoding/encoding.rb, line 29
def decode(data)
  if prefix.present? && data.start_with?(prefix)
    data = data[prefix.size..-1]
  end

  decoded = data.chars
  decoded = unpad_encoded_points(decoded)
  decoded = bits_from_encoded_points(decoded)
  decoded = unpad_bits(decoded)
  decoded = bytes_for(decoded)
  decoded = decoded.pack("c*")
  decoded
end
encode(data) click to toggle source
# File lib/radix_encoding/encoding.rb, line 43
def encode(data)
  case data
  when String
    encode_bytes(data.bytes)
  else
    raise DataTypeNotSupportedError.new(data_type: data.class)
  end
end
pad_bits(bits, padded_bitsize) click to toggle source
# File lib/radix_encoding/encoding/bits.rb, line 30
def pad_bits(bits, padded_bitsize)
  Subvisual::ArrayUtils.pad_right(bits, padded_bitsize, "0")
end
unpad_bits(bits) click to toggle source
# File lib/radix_encoding/encoding/bits.rb, line 34
def unpad_bits(bits)
  excess_bits = bits.size % 8

  return bits if excess_bits.zero?

  bits[0...-excess_bits]
end

Private Instance Methods

chunk_bitsize() click to toggle source
# File lib/radix_encoding/encoding.rb, line 56
def chunk_bitsize
  @chunk_bitsize ||=
    Subvisual::MathUtils.least_common_denominator(lower_power, 8)
end
encode_bytes(bytes) click to toggle source
# File lib/radix_encoding/encoding.rb, line 61
def encode_bytes(bytes)
  bits = bits_for(bytes)
  padded_bitsize = chunks_total_bitsize_for(bits)
  padding_count = count_encoded_points_in(padded_bitsize - bits.size)

  encoded = pad_bits(bits, padded_bitsize)
  encoded = encoded_points_for(encoded)
  encoded = clean_encoded_points(encoded, padding_count)
  encoded = pad_encoded_points(encoded, padding_count)
  encoded = encoded.join

  "#{prefix}#{encoded}"
end
encoded_point_bitsize() click to toggle source
# File lib/radix_encoding/encoding.rb, line 75
def encoded_point_bitsize
  @encoded_point_bitsize ||= chunk_bitsize / encoded_points_per_chunk
end
encoded_points_per_chunk() click to toggle source
# File lib/radix_encoding/encoding.rb, line 79
def encoded_points_per_chunk
  @encoded_points_per_chunk ||= chunk_bitsize / lower_power
end
lower_power() click to toggle source
# File lib/radix_encoding/encoding.rb, line 83
def lower_power
  @lower_power ||= if radix == 2**upper_power
                     upper_power
                   else
                     upper_power - 1
                   end
end
upper_power() click to toggle source
# File lib/radix_encoding/encoding.rb, line 91
def upper_power
  @upper_power ||= begin
                     power = 0
                     power += 1 while 2**power < radix
                     power
                   end
end