diff miscutil/make-imeisv.c @ 744:2dcfad8a3ed0

make-imeisv utility written
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 19 Oct 2020 06:35:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscutil/make-imeisv.c	Mon Oct 19 06:35:35 2020 +0000
@@ -0,0 +1,76 @@
+/*
+ * This utility constructs a 16-digit IMEISV from a 15-digit IMEI
+ * (which must have a valid Luhn check digit) and a 2-digit SV field.
+ * It is intended for use in shell scripts.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+parse_imei_arg(input, buf)
+	char *input, *buf;
+{
+	char *cp;
+	int i;
+
+	cp = input;
+	if (!isdigit(*cp)) {
+inv:		fprintf(stderr,
+			"error: IMEI argument must have 15 decimal digits\n");
+		exit(1);
+	}
+	for (i = 0; i < 15; i++) {
+		if (ispunct(*cp))
+			cp++;
+		if (!isdigit(*cp))
+			goto inv;
+		buf[i] = *cp++;
+	}
+	if (*cp)
+		goto inv;
+}
+
+check_luhn(digits)
+	char *digits;
+{
+	int i, dig, sum;
+
+	sum = 0;
+	for (i = 0; i < 14; i++) {
+		dig = digits[i] - '0';
+		if (i & 1) {
+			dig *= 2;
+			if (dig > 9)
+				dig -= 9;
+		}
+		sum += dig;
+	}
+	dig = sum % 10;
+	if (dig)
+		dig = 10 - dig;
+	if (digits[14] != dig + '0') {
+		fprintf(stderr, "error: given IMEI fails Luhn check\n");
+		exit(1);
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	char imeibuf[15];
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s IMEI SV\n", argv[0]);
+		exit(1);
+	}
+	parse_imei_arg(argv[1], imeibuf);
+	check_luhn(imeibuf);
+	if (!isdigit(argv[2][0]) || !isdigit(argv[2][1]) || argv[2][2]) {
+		fprintf(stderr,
+			"error: SV argument must have 2 decimal digits\n");
+		exit(1);
+	}
+	printf("%.8s-%.6s-%s\n", imeibuf, imeibuf + 8, argv[2]);
+	exit(0);
+}