Sha256: 74f2cb94aaa6a8556f78a60a3698e9a81d45af5fa1972adc9cb3a43bf05a0b5e

Contents?: true

Size: 1.01 KB

Versions: 1

Compression:

Stored size: 1.01 KB

Contents

# frozen_string_literal: true

module SecId
  # https://en.wikipedia.org/wiki/SEDOL
  class SEDOL < Base
    ID_REGEX = /\A
      (?<identifier>[0-9BCDFGHJKLMNPQRSTVWXYZ]{6})
      (?<check_digit>\d)?
    \z/x

    CHARACTER_WEIGHTS = [1, 3, 1, 7, 3, 9].freeze

    def initialize(sedol)
      sedol_parts = parse sedol
      @identifier = sedol_parts[:identifier]
      @check_digit = sedol_parts[:check_digit]&.to_i
    end

    def calculate_check_digit
      unless valid_format?
        raise InvalidFormatError, "SEDOL '#{full_number}' is invalid and check-digit cannot be calculated!"
      end

      mod10(weighted_sum)
    end

    private

    # NOTE: I know this isn't the most idiomatic Ruby code, but it's the fastest one
    def weighted_sum
      index = 0
      sum = 0

      while index < id_digits.size
        sum += id_digits[index] * CHARACTER_WEIGHTS[index]
        index += 1
      end

      sum
    end

    def id_digits
      @id_digits ||= identifier.each_char.map(&method(:char_to_digit))
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
sec_id-4.1.0 lib/sec_id/sedol.rb