changeset 271:cd043e690621

imei-luhn utility written
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Fri, 07 Feb 2014 05:00:24 +0000
parents d1388095ab27
children 9c34d938a645
files .hgignore miscutil/Makefile miscutil/imei-luhn.c
diffstat 3 files changed, 96 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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$
--- /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
--- /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;
+	}
+}