Class: Pubid::Isbn::CheckDigit
- Inherits:
-
Object
- Object
- Pubid::Isbn::CheckDigit
- Defined in:
- lib/pubid/isbn/check_digit.rb
Overview
Pure-functional check digit math for ISBN-10 and ISBN-13 per ISO 2108.
ISBN-10: weighted sum with weights 10..1, mod 11. Check digit 10 is rendered as "X". ISBN-13: weighted sum with alternating weights 1/3, mod 10. Check digit is 0-9.
Class Method Summary collapse
-
.compute_isbn10(payload) ⇒ String
Compute the correct ISBN-10 check digit for a 9-digit payload.
-
.compute_isbn13(payload) ⇒ String
Compute the correct ISBN-13 check digit for a 12-digit payload.
-
.valid?(full) ⇒ Boolean
Verify the check digit on a full 10- or 13-digit ISBN string.
Class Method Details
.compute_isbn10(payload) ⇒ String
Compute the correct ISBN-10 check digit for a 9-digit payload.
14 15 16 17 18 19 20 |
# File 'lib/pubid/isbn/check_digit.rb', line 14 def self.compute_isbn10(payload) raise ArgumentError, "ISBN-10 payload must be 9 digits" unless payload.to_s.match?(/\A\d{9}\z/) sum = payload.to_s.each_char.with_index.sum { |c, i| c.to_i * (10 - i) } digit = (11 - sum % 11) % 11 digit == 10 ? "X" : digit.to_s end |
.compute_isbn13(payload) ⇒ String
Compute the correct ISBN-13 check digit for a 12-digit payload.
24 25 26 27 28 29 30 31 |
# File 'lib/pubid/isbn/check_digit.rb', line 24 def self.compute_isbn13(payload) raise ArgumentError, "ISBN-13 payload must be 12 digits" unless payload.to_s.match?(/\A\d{12}\z/) sum = payload.to_s.each_char.with_index.sum do |c, i| c.to_i * (i.even? ? 1 : 3) end ((10 - sum % 10) % 10).to_s end |
.valid?(full) ⇒ Boolean
Verify the check digit on a full 10- or 13-digit ISBN string.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/pubid/isbn/check_digit.rb', line 36 def self.valid?(full) digits = full.to_s.upcase.delete("^0-9X") case digits.length when 10 payload = digits[0, 9] actual = digits[9] compute_isbn10(payload) == actual when 13 payload = digits[0, 12] actual = digits[12] compute_isbn13(payload) == actual else false end end |