Module: SecID::Checkable
Overview
Provides check-digit validation and calculation for securities identifiers. Include this module in classes that have a check digit as part of their format.
Including classes must implement:
-
calculate_check_digitmethod that returns the calculated check digit value
This module provides:
-
Character-to-digit mapping constants
-
Luhn algorithm variants for check-digit calculation
-
valid?override that validates format and check digit -
restoremethod returning full identifier string without mutation -
restore!method to calculate and set the check digit, returningself -
check_digitattribute -
Class-level convenience methods:
restore,restore!,check_digit
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- CHAR_TO_DIGITS =
Character-to-digit mapping for Luhn algorithm variants. Maps alphanumeric characters to digit arrays for multi-digit expansion. Used by ISIN for check-digit calculation.
{ '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => [1, 0], 'B' => [1, 1], 'C' => [1, 2], 'D' => [1, 3], 'E' => [1, 4], 'F' => [1, 5], 'G' => [1, 6], 'H' => [1, 7], 'I' => [1, 8], 'J' => [1, 9], 'K' => [2, 0], 'L' => [2, 1], 'M' => [2, 2], 'N' => [2, 3], 'O' => [2, 4], 'P' => [2, 5], 'Q' => [2, 6], 'R' => [2, 7], 'S' => [2, 8], 'T' => [2, 9], 'U' => [3, 0], 'V' => [3, 1], 'W' => [3, 2], 'X' => [3, 3], 'Y' => [3, 4], 'Z' => [3, 5], '*' => [3, 6], '@' => [3, 7], '#' => [3, 8] }.freeze
- CHAR_TO_DIGIT =
Character-to-digit mapping for single-digit conversion. Maps alphanumeric characters to values 0-38 (A=10, B=11, …, Z=35, *=36, @=37, #=38). Used by CUSIP, FIGI, SEDOL, LEI, and IBAN for check-digit calculations.
{ '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, '*' => 36, '@' => 37, '#' => 38 }.freeze
Class Method Summary collapse
- .included(base) ⇒ Object private
Instance Method Summary collapse
-
#calculate_check_digit ⇒ Integer
Subclasses must override this method to implement their check-digit algorithm.
-
#restore ⇒ String
Returns the full identifier string with correct check digit without mutation.
-
#restore! ⇒ self
Calculates and sets the check digit, updating full_id.
- #to_s ⇒ String
-
#valid? ⇒ Boolean
Validates format and check digit.
Class Method Details
.included(base) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
60 61 62 63 |
# File 'lib/sec_id/concerns/checkable.rb', line 60 def self.included(base) base.attr_reader :check_digit base.extend(ClassMethods) end |
Instance Method Details
#calculate_check_digit ⇒ Integer
Subclasses must override this method to implement their check-digit algorithm.
123 124 125 |
# File 'lib/sec_id/concerns/checkable.rb', line 123 def calculate_check_digit raise NotImplementedError end |
#restore ⇒ String
Returns the full identifier string with correct check digit without mutation.
104 105 106 |
# File 'lib/sec_id/concerns/checkable.rb', line 104 def restore "#{identifier}#{calculate_check_digit.to_s.rjust(check_digit_width, '0')}" end |
#restore! ⇒ self
Calculates and sets the check digit, updating full_id.
112 113 114 115 116 |
# File 'lib/sec_id/concerns/checkable.rb', line 112 def restore! @check_digit = calculate_check_digit @full_id = to_s self end |
#to_s ⇒ String
128 129 130 |
# File 'lib/sec_id/concerns/checkable.rb', line 128 def to_s "#{identifier}#{check_digit&.to_s&.rjust(check_digit_width, '0')}" end |
#valid? ⇒ Boolean
Validates format and check digit.
96 97 98 |
# File 'lib/sec_id/concerns/checkable.rb', line 96 def valid? super && check_digit == calculate_check_digit end |