55 lines
1.1 KiB
C
55 lines
1.1 KiB
C
/*
|
|||
|
|
* 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;
|
||
|
|
}
|