Created
March 17, 2016 00:47
-
-
Save celoyd/a3f1b515929493f512d5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Calculate an ISO 6346 check digit (probably). | |
# The official algorithm costs about $100 to know. | |
# By Charlie Loyd, 2008-04-11. | |
from re import compile as regex | |
from string import uppercase | |
def iso6346checksum(code, ten='error'): | |
'''Call with a string like 'TEXU 328422' and optionally ten= | |
what you want a check digit of 10 to return instead of an error | |
(probably 0 or 10)''' | |
valid = regex('[A-Z]{3}[UJZ] [0-9]{6}') | |
if not valid.match(code): | |
raise ValueError, code + ' should look like "ZZZZ 111111".' | |
prefix, suffix = code.split() | |
prefix = list(prefix) | |
# Letter values are A=10, etc., skipping those divisible by 11, so Z=38 | |
lettervals = filter(lambda e: e % 11 != 0, range(10, 39)) | |
lettertable = dict(zip(uppercase, lettervals)) | |
prefix = [lettertable[l] for l in prefix] | |
code = prefix + map(int, list(suffix)) | |
s = sum([code[ind] * 2**ind for ind in range(0, 10)]) | |
dummy = int(s/11) * 11 # futureproof! | |
cksum = s - dummy | |
if cksum == 10: | |
if ten == 'error': | |
raise ValueError, 'ISO 6346 checksum of 10.' | |
else: return ten | |
else: return cksum |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment