validation.gs1-check-digit@1.0.0
impl/python/gs1_check_digit.py
1,009 bytes · the Python implementation · view raw
def _ascii_digits(value: object) -> bool:
# Compare against ASCII explicitly: str.isdigit() accepts Arabic-Indic and
# superscript digits, which the other two languages would reject.
return isinstance(value, str) and value != "" and all("0" <= ch <= "9" for ch in value)
def gs1_check_digit(data: str) -> int:
"""The GS1 mod-10 check digit for `data`, the digits of a GS1 key without
its check digit.
One rule serves every key length because the weights are counted from the
right: 3, 1, 3, 1 ... starting with the digit that will sit next to the
check digit. Counting from the left instead only works for EAN-13 and the
other even-length data strings.
"""
if not _ascii_digits(data):
raise ValueError("GS1 data must be one or more ASCII digits, received %r" % (data,))
total = 0
weight = 3
for ch in reversed(data):
total = (total + (ord(ch) - 48) * weight) % 10
weight = 1 if weight == 3 else 3
return (10 - total) % 10