annotate miscutil/imei-luhn.c @ 462:6500e1817d9b

doc/Roadmap: written
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 23 Jun 2014 20:39:36 +0000
parents cd043e690621
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
271
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1 /*
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2 * This program computes the Luhn check digit for an IMEI number given
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
3 * the first 14 digits, or verifies the correctness of this check digit
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
4 * given a 15-digit number as input.
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
5 *
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 * The number given on the command line may optionally include punctuation,
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 * which is skipped and ignored.
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 */
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10 #include <stdio.h>
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11 #include <ctype.h>
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 #include <stdlib.h>
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14 char digits[15];
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 compute_cd()
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17 {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18 int i, dig, sum;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20 sum = 0;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 for (i = 0; i < 14; i++) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22 dig = digits[i];
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 if (i & 1) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 dig *= 2;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25 if (dig > 9)
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 dig -= 9;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28 sum += dig;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 dig = sum % 10;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31 if (dig)
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 dig = 10 - dig;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 return dig;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 main(argc, argv)
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37 char **argv;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39 char *cp;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 int i;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42 if (argc != 2) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 usage: fprintf(stderr, "usage: %s number\n", argv[0]);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44 exit(2);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46 cp = argv[1];
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47 if (!isdigit(*cp))
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 goto usage;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 for (i = 0; *cp; ) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50 if (ispunct(*cp))
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51 cp++;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 if (!isdigit(*cp))
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 goto usage;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54 if (i >= 15) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 wrong_len: fprintf(stderr,
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56 "error: argument must have 14 or 15 digits\n");
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57 exit(2);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 digits[i++] = *cp++ - '0';
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 switch (i) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 case 14:
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
63 printf("%d\n", compute_cd());
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
64 exit(0);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
65 case 15:
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
66 if (digits[14] == compute_cd()) {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
67 printf("IMEI OK\n");
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
68 exit(0);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
69 } else {
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
70 printf("Check digit mismatch!\n");
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
71 exit(1);
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
72 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
73 default:
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
74 goto wrong_len;
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
75 }
cd043e690621 imei-luhn utility written
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
76 }