diff options
| author | Mattias Andrée <m@maandree.se> | 2025-12-27 22:37:47 +0100 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2025-12-27 22:37:47 +0100 |
| commit | 4506c1e56ec89ad42c1a37f4b9b41204e4d991d1 (patch) | |
| tree | 477d80ea90a4d827e70bb5d85781c1e366cee124 /luhncheck.c | |
| download | luhncheck-4506c1e56ec89ad42c1a37f4b9b41204e4d991d1.tar.gz luhncheck-4506c1e56ec89ad42c1a37f4b9b41204e4d991d1.tar.bz2 luhncheck-4506c1e56ec89ad42c1a37f4b9b41204e4d991d1.tar.xz | |
First commit
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
| -rw-r--r-- | luhncheck.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/luhncheck.c b/luhncheck.c new file mode 100644 index 0000000..51f04ab --- /dev/null +++ b/luhncheck.c @@ -0,0 +1,81 @@ +/* See LICENSE file for copyright and license details. */ +#include <libsimple-arg.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +NUSAGE(2, "number ..."); + + +static int +check_luhn(const char *s) +{ + unsigned sum = 0; + + switch (strlen(s) & 1U) { + for (;;) { + case 0: + if ('0' <= *s && *s <= '4') + sum += 2U * (unsigned)(*s - '0'); + else if ('5' <= *s && *s <= '9') + sum += 2U * (unsigned)(*s - '0') - 9U; + else if (*s) + return 0; + else + break; + s++; + + case 1: + if ('0' <= *s && *s <= '9') + sum += (unsigned)(*s - '0'); + else if (*s) + return 0; + else + break; + s++; + + sum %= 10U; + } + } + + return (sum % 10U) == 0U; +} + + +int +main(int argc, char *argv[]) +{ + int use_colour; + int ret = 0; + int r, ok; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (!argc) + usage(); + + use_colour = isatty(STDOUT_FILENO); + + for (; *argv; argv++) { + ok = check_luhn(*argv); + ret |= !ok; + r = printf("%s%s %s%s\n", use_colour ? ok ? "\033[1;32m" : "\033[1;31m" : "", + *argv, ok ? "is OK" : "is invalid", use_colour ? "\033[m" : ""); + if (r < 0) { + fprintf(stderr, "%s: printf: %s\n", argv0, strerror(errno)); + exit(2); + } + } + + if (fflush(stdout) || fclose(stdout)) { + fprintf(stderr, "%s: printf: %s\n", argv0, strerror(errno)); + exit(2); + } + + return ret; +} |
