class ISO7064

Constants

ALPHANUMERIC_CHAR_SET
ALPHA_CHAR_SET
HEX_CHAR_SET
MOD_112_CHAR_SET
MOD_372_CHAR_SET
NUMERIC_CHAR_SET

Public Instance Methods

calculate_alph_check_digit(value, double_digit) click to toggle source

Calculates ISO 7064 MOD 27,26 in single digit mode and MOD 661,26 in double digit mode.

# File lib/iso7064.rb, line 109
def calculate_alph_check_digit(value, double_digit)
  return calculate_check_digit(value, ALPHA_CHAR_SET, double_digit)
end
calculate_alphanumeric_check_digit(value, double_digit) click to toggle source

Calculates ISO 7064 MOD 37,36 in single digit mode and MOD 1271,36 in double digit mode.

# File lib/iso7064.rb, line 119
def calculate_alphanumeric_check_digit(value, double_digit)
  return calculate_check_digit(value, ALPHANUMERIC_CHAR_SET, double_digit)
end
calculate_check_digit(value, char_set, double_digit) click to toggle source
# File lib/iso7064.rb, line 9
def calculate_check_digit(value, char_set, double_digit)
  radix, modulus = get_check_digit_radix_and_modulus(char_set, double_digit)

  if modulus != radix + 1
    return calculate_pure_system_check_digit(value, radix, modulus, char_set, double_digit)
  else
    return calculate_hybrid_system_check_digit(value, char_set)
  end
end
calculate_hex_check_digit(value, double_digit) click to toggle source

Calculates ISO 7064 MOD 17,16 in single digit mode and MOD 251,16 in double digit mode.

# File lib/iso7064.rb, line 99
def calculate_hex_check_digit(value, double_digit)
  return calculate_check_digit(value, HEX_CHAR_SET, double_digit)
end
calculate_hybrid_system_check_digit(value, char_set) click to toggle source

Algorithm from: www.codeproject.com/Articles/16540/Error-Detection-Based-on-Check-Digit-Schemes

# File lib/iso7064.rb, line 46
def calculate_hybrid_system_check_digit(value, char_set)
  return nil if value.nil? || value.empty?

  value = value.upcase
  radix = char_set.length
  pos = radix

  value.each_char do |c|
    i = char_set.index(c)
    return nil if i == -1
    pos += i
    pos -= radix if pos > radix
    pos *= 2
    pos -= radix + 1 if pos >= radix + 1
  end

  pos = radix + 1 - pos
  pos = 0 if (pos == radix)
  return value + char_set[pos]
end
calculate_numeric_check_digit(value, double_digit) click to toggle source

Calculates ISO 7064 MOD 11,10 in single digit mode and MOD 97,10 in double digit mode.

# File lib/iso7064.rb, line 89
def calculate_numeric_check_digit(value, double_digit)
  return calculate_check_digit(value, NUMERIC_CHAR_SET, double_digit)
end
calculate_pure_system_check_digit(value, radix, modulus, char_set, double_digit) click to toggle source

Algorithm from: github.com/danieltwagner/iso7064.

# File lib/iso7064.rb, line 20
def calculate_pure_system_check_digit(value,  radix,  modulus, char_set, double_digit)
  return nil if value.nil? || value.empty?

  value = value.upcase
  p = 0

  value.each_char do |c|
    i = char_set.index(c)
    return nil if i == -1
    p = ((p + i) * radix) % modulus
  end

  p = (p * radix) % modulus if double_digit

  check_digit = (modulus - p + 1) % modulus

  if double_digit
    second = check_digit % radix
    first = (check_digit - second) / radix
    return value + char_set[first] + char_set[second]
  else
    return value + char_set[check_digit]
  end
end
verify_alpha_check_digit(value, double_digit) click to toggle source

Verifies ISO 7064 MOD 27,26 in single digit mode and MOD 661,26 in double digit mode.

# File lib/iso7064.rb, line 114
def verify_alpha_check_digit(value, double_digit)
  return verify_check_digit(value, ALPHA_CHAR_SET, double_digit)
end
verify_alphanumeric_check_digit(value, double_digit) click to toggle source

Verifies ISO 7064 MOD 37,36 in single digit mode and MOD 1271,36 in double digit mode.

# File lib/iso7064.rb, line 124
def verify_alphanumeric_check_digit(value, double_digit)
  return verify_check_digit(value, ALPHANUMERIC_CHAR_SET, double_digit)
end
verify_check_digit(value, char_set, double_digit) click to toggle source

Verifies that the last character(s) of the supplied value are valid check digit(s).

# File lib/iso7064.rb, line 68
def verify_check_digit(value, char_set, double_digit)
  radix, modulus = get_check_digit_radix_and_modulus(char_set, double_digit)
  return verify_check_digit_by_radix_and_modulus(value, radix, modulus, char_set, double_digit)
end
verify_check_digit_by_radix_and_modulus(value, radix, modulus, char_set, double_digit) click to toggle source
# File lib/iso7064.rb, line 73
def verify_check_digit_by_radix_and_modulus(value, radix, modulus, char_set, double_digit)
  num_digits = (double_digit ? 2 : 1)

  return false if (value == null || value.length <= num_digits)

  value = value.upcase
  orig_value = value[0, value.length - num_digits]

  if (modulus != radix + 1)
    return (value == calculate_pure_system_check_digit(orig_value, radix, modulus, char_set, double_digit))
  else
    return (value == calculate_hybrid_system_check_digit(orig_value, char_set))
  end
end
verify_hex_check_digit(value, double_digit) click to toggle source

Verifies ISO 7064 MOD 11,10 in single digit mode and MOD 97,10 in double digit mode.

# File lib/iso7064.rb, line 104
def verify_hex_check_digit(value, double_digit)
  return verify_check_digit(value, HEX_CHAR_SET, double_digit)
end
verify_numeric_check_digit(value, double_digit) click to toggle source

Verifies ISO 7064 MOD 11,10 in single digit mode and MOD 97,10 in double digit mode.

# File lib/iso7064.rb, line 94
def verify_numeric_check_digit(value, double_digit)
  return verify_check_digit(value, NUMERIC_CHAR_SET, double_digit)
end

Private Instance Methods

get_check_digit_radix_and_modulus(char_set, double_digit) click to toggle source

Returns the correct ISO 7064 radix and modulus for the given character set and digit count.

# File lib/iso7064.rb, line 130
def get_check_digit_radix_and_modulus(char_set, double_digit)
  radix = char_set.length
  modulus = radix + 1

  if (double_digit)
    # The modulus numbers below for double digit calculations are defined by ISO 7064.
    case (radix)
    when 10 then modulus = 97
      #Mod 251,16 isn't defined in ISO 7064, but it could be useful so I added it anyway.
    when 16 then modulus = 251
    when 26 then modulus = 661
    when 36 then modulus = 1271
    end
  elsif (radix == 11)
    # MOD 11,2 - Single digit 0-9 check with an added 'X' check digit.
    modulus = 11
    radix = 2
  elsif (radix == 37)
    # MOD 37,2 - Single digit 0-9,A-Z check with an added '*' check digit.
    modulus = 37
    radix = 2
  end
  raise 'Invalid character set' if (radix != 2 && radix != 10 && radix != 16 && radix != 26 && radix != 36)
  return radix, modulus
end