# HG changeset patch # User Michael Spacefalcon # Date 1391749224 0 # Node ID cd043e690621e3e734051d40ee79819b0b3ce0ca # Parent d1388095ab2791303bdd1dd721a67c1655b3be11 imei-luhn utility written diff -r d1388095ab27 -r cd043e690621 .hgignore --- a/.hgignore Thu Feb 06 09:54:02 2014 +0000 +++ b/.hgignore Fri Feb 07 05:00:24 2014 +0000 @@ -20,6 +20,8 @@ ^loadtools/fc-loadtool$ ^loadtools/fc-xram$ +^miscutil/imei-luhn$ + ^rvinterf/lowlevel/rvinterf$ ^rvinterf/lowlevel/rvtdump$ ^rvinterf/old/etmsend$ diff -r d1388095ab27 -r cd043e690621 miscutil/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/miscutil/Makefile Fri Feb 07 05:00:24 2014 +0000 @@ -0,0 +1,18 @@ +CC= gcc +CFLAGS= -O2 +PROGS= imei-luhn +INSTBIN=/usr/local/bin + +all: ${PROGS} + +${PROGS}: + ${CC} ${CFLAGS} -o $@ $@.c + +imei-luhn: imei-luhn.c + +install: ${PROGS} + mkdir -p ${INSTBIN} + install -c ${PROGS} ${INSTBIN} + +clean: + rm -f ${PROGS} *.o *errs *.out diff -r d1388095ab27 -r cd043e690621 miscutil/imei-luhn.c --- /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 +#include +#include + +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; + } +}