Sha256: 044afd514e9b3f9f5f49202c96dab9231e9056a17544637e7248dd82946c7bea

Contents?: true

Size: 1.17 KB

Versions: 9

Compression:

Stored size: 1.17 KB

Contents

module GS1
  # GS1 check digit calculation
  #
  # Implementation of: http://www.gs1.org/how-calculate-check-digit-manually
  # Notice! This class does not validate the format of the given sequence,
  # only the length.
  #
  class CheckDigitCalculator
    MULTIPLIER_ARRAY = [3, 1] * 9
    VALID_LENGTHS = [7, 11, 12, 13, 17].freeze

    def initialize(sequence)
      @sequence = sequence
      @reverse_sequence = sequence.chars.reverse

      raise ArgumentError, 'Invalid length' unless VALID_LENGTHS.include?(sequence.size)
    end

    def self.from_sequence(sequence)
      new(sequence).check_digit
    end

    def self.with_sequence(sequence)
      new(sequence).calculate_sequence_with_digit
    end

    def check_digit
      sub_from_nearest_higher_ten.to_s
    end

    def calculate_sequence_with_digit
      sequence + check_digit
    end

    private

    attr_reader :sequence, :reverse_sequence

    def multiplied_sequence
      @multiplied_sequence ||= reverse_sequence.each_with_index.map do |digit, idx|
        digit.to_i * MULTIPLIER_ARRAY[idx]
      end
    end

    def sub_from_nearest_higher_ten
      (10 - (multiplied_sequence.inject(:+) % 10)) % 10
    end
  end
end

Version data entries

9 entries across 9 versions & 1 rubygems

Version Path
gs1-1.0.0 lib/gs1/check_digit_calculator.rb
gs1-0.1.8 lib/gs1/check_digit_calculator.rb
gs1-0.1.7 lib/gs1/check_digit_calculator.rb
gs1-0.1.6 lib/gs1/check_digit_calculator.rb
gs1-0.1.5 lib/gs1/check_digit_calculator.rb
gs1-0.1.3 lib/gs1/check_digit_calculator.rb
gs1-0.1.2 lib/gs1/check_digit_calculator.rb
gs1-0.1.1 lib/gs1/check_digit_calculator.rb
gs1-0.1.0 lib/gs1/check_digit_calculator.rb