1# mod_11_2.py - functions for performing the ISO 7064 Mod 11, 2 algorithm 2# 3# Copyright (C) 2010, 2011, 2012, 2013 Arthur de Jong 4# 5# This library is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Lesser General Public 7# License as published by the Free Software Foundation; either 8# version 2.1 of the License, or (at your option) any later version. 9# 10# This library is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with this library; if not, write to the Free Software 17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18# 02110-1301 USA 19 20"""The ISO 7064 Mod 11, 2 algorithm. 21 22The Mod 11, 2 algorithm is a simple module 11 checksum where the check 23digit can be an X to make the number valid. 24 25For a module that can do generic Mod x, 2 calculations see the 26:mod:`stdnum.iso7064.mod_37_2` module. 27 28>>> calc_check_digit('0794') 29'0' 30>>> validate('07940') 31'07940' 32>>> calc_check_digit('079') 33'X' 34>>> validate('079X') 35'079X' 36>>> checksum('079X') 371 38""" 39 40from stdnum.exceptions import * 41 42 43def checksum(number): 44 """Calculate the checksum. A valid number should have a checksum of 1.""" 45 check = 0 46 for n in number: 47 check = (2 * check + int(10 if n == 'X' else n)) % 11 48 return check 49 50 51def calc_check_digit(number): 52 """Calculate the extra digit that should be appended to the number to 53 make it a valid number.""" 54 c = (1 - 2 * checksum(number)) % 11 55 return 'X' if c == 10 else str(c) 56 57 58def validate(number): 59 """Check whether the check digit is valid.""" 60 try: 61 valid = checksum(number) == 1 62 except Exception: 63 raise InvalidFormat() 64 if not valid: 65 raise InvalidChecksum() 66 return number 67 68 69def is_valid(number): 70 """Check whether the check digit is valid.""" 71 try: 72 return bool(validate(number)) 73 except ValidationError: 74 return False 75