FreeCalypso > hg > freecalypso-sw
comparison 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 |
comparison
equal
deleted
inserted
replaced
270:d1388095ab27 | 271:cd043e690621 |
---|---|
1 /* | |
2 * This program computes the Luhn check digit for an IMEI number given | |
3 * the first 14 digits, or verifies the correctness of this check digit | |
4 * given a 15-digit number as input. | |
5 * | |
6 * The number given on the command line may optionally include punctuation, | |
7 * which is skipped and ignored. | |
8 */ | |
9 | |
10 #include <stdio.h> | |
11 #include <ctype.h> | |
12 #include <stdlib.h> | |
13 | |
14 char digits[15]; | |
15 | |
16 compute_cd() | |
17 { | |
18 int i, dig, sum; | |
19 | |
20 sum = 0; | |
21 for (i = 0; i < 14; i++) { | |
22 dig = digits[i]; | |
23 if (i & 1) { | |
24 dig *= 2; | |
25 if (dig > 9) | |
26 dig -= 9; | |
27 } | |
28 sum += dig; | |
29 } | |
30 dig = sum % 10; | |
31 if (dig) | |
32 dig = 10 - dig; | |
33 return dig; | |
34 } | |
35 | |
36 main(argc, argv) | |
37 char **argv; | |
38 { | |
39 char *cp; | |
40 int i; | |
41 | |
42 if (argc != 2) { | |
43 usage: fprintf(stderr, "usage: %s number\n", argv[0]); | |
44 exit(2); | |
45 } | |
46 cp = argv[1]; | |
47 if (!isdigit(*cp)) | |
48 goto usage; | |
49 for (i = 0; *cp; ) { | |
50 if (ispunct(*cp)) | |
51 cp++; | |
52 if (!isdigit(*cp)) | |
53 goto usage; | |
54 if (i >= 15) { | |
55 wrong_len: fprintf(stderr, | |
56 "error: argument must have 14 or 15 digits\n"); | |
57 exit(2); | |
58 } | |
59 digits[i++] = *cp++ - '0'; | |
60 } | |
61 switch (i) { | |
62 case 14: | |
63 printf("%d\n", compute_cd()); | |
64 exit(0); | |
65 case 15: | |
66 if (digits[14] == compute_cd()) { | |
67 printf("IMEI OK\n"); | |
68 exit(0); | |
69 } else { | |
70 printf("Check digit mismatch!\n"); | |
71 exit(1); | |
72 } | |
73 default: | |
74 goto wrong_len; | |
75 } | |
76 } |