/*
 * upc.c - UPC-A validation.
 *
 * A UPC-A barcode is 12 digits. The last digit is a mod-10 checksum over the
 * first 11: digits in odd positions (1,3,5,7,9,11) are weighted x3 and digits
 * in even positions (2,4,6,8,10) x1; the check digit is whatever makes the
 * weighted total a multiple of 10.
 */
#include "upc.h"

static int allDigits(const char *s, int n)
{
    int i;
    for (i = 0; i < n; i++) {
        if (s[i] < '0' || s[i] > '9')
            return 0;
    }
    return 1;
}

int upcCheckDigit(const char *s)
{
    int i, sum = 0;

    if (!allDigits(s, 11))
        return -1;

    for (i = 0; i < 11; i++) {
        int d = s[i] - '0';
        if ((i % 2) == 0)   /* 0-based even index = 1st,3rd,... digit: weight 3 */
            sum += 3 * d;
        else
            sum += d;
    }
    return (10 - (sum % 10)) % 10;
}

int upcIsValid(const char *s)
{
    int n = 0;
    int check;

    while (s[n] != '\0')
        n++;
    if (n != UPC_A_LEN)
        return 0;
    if (!allDigits(s, UPC_A_LEN))
        return 0;

    check = upcCheckDigit(s);
    if (check < 0)
        return 0;
    return (s[11] - '0') == check;
}
