FreeCalypso > hg > freecalypso-sw
diff miscutil/imei-luhn.c @ 271:cd043e690621
imei-luhn utility written
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 07 Feb 2014 05:00:24 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/miscutil/imei-luhn.c Fri Feb 07 05:00:24 2014 +0000 @@ -0,0 +1,76 @@ +/* + * This program computes the Luhn check digit for an IMEI number given + * the first 14 digits, or verifies the correctness of this check digit + * given a 15-digit number as input. + * + * The number given on the command line may optionally include punctuation, + * which is skipped and ignored. + */ + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +char digits[15]; + +compute_cd() +{ + int i, dig, sum; + + sum = 0; + for (i = 0; i < 14; i++) { + dig = digits[i]; + if (i & 1) { + dig *= 2; + if (dig > 9) + dig -= 9; + } + sum += dig; + } + dig = sum % 10; + if (dig) + dig = 10 - dig; + return dig; +} + +main(argc, argv) + char **argv; +{ + char *cp; + int i; + + if (argc != 2) { +usage: fprintf(stderr, "usage: %s number\n", argv[0]); + exit(2); + } + cp = argv[1]; + if (!isdigit(*cp)) + goto usage; + for (i = 0; *cp; ) { + if (ispunct(*cp)) + cp++; + if (!isdigit(*cp)) + goto usage; + if (i >= 15) { +wrong_len: fprintf(stderr, + "error: argument must have 14 or 15 digits\n"); + exit(2); + } + digits[i++] = *cp++ - '0'; + } + switch (i) { + case 14: + printf("%d\n", compute_cd()); + exit(0); + case 15: + if (digits[14] == compute_cd()) { + printf("IMEI OK\n"); + exit(0); + } else { + printf("Check digit mismatch!\n"); + exit(1); + } + default: + goto wrong_len; + } +}