diff options
author | Jakob Kaivo <jkk@ung.org> | 2019-11-21 14:50:39 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2019-11-21 14:50:39 -0500 |
commit | c02867e0a3368e58248d6f59b4d0b9806a7216c5 (patch) | |
tree | 9ce0f1d259300728c3dd3e9c26394cb4be890cd5 | |
parent | 260e33f13acbdd2bbedf97a2c5e567bdc099d6dc (diff) |
working
-rw-r--r-- | cksum.c | 62 |
1 files changed, 45 insertions, 17 deletions
@@ -17,7 +17,7 @@ * */ -#define _POSIX_C_SOURCE 2 +#define _POSIX_C_SOURCE 200809L #include <errno.h> #include <inttypes.h> #include <limits.h> @@ -26,16 +26,51 @@ #include <string.h> #include <unistd.h> -/* TODO: study http://ross.net/crc/download/crc_v3.txt */ +#define MAX_SUM_WIDTH (32) +#define UINT32_BIT (32) -int cksum(const char *path) +struct sum { + uintmax_t size; + char sum[MAX_SUM_WIDTH]; +}; + +static uint32_t reverse(uint32_t n, int width) +{ + uint32_t r = 0; + for (int i = 0; i < width; i++) { + r |= (n & 0x1) << ((width - 1) - i); + n >>= 1; + } + return r; +} + +static struct sum crc32(FILE *f) { - const uint_least32_t polynomial = - /* 0x04c11db7; */ /* x^32 is implicit */ - 0x82608edb; /* +1 is implicit */ + const uint32_t polynomial = 0x04c11db7; + uint32_t crc = UINT32_MAX; + struct sum sum = { 0 }; + + int c; + while ((c = fgetc(f)) != EOF) { + sum.size++; + crc ^= reverse((uint8_t)c, CHAR_BIT) << (UINT32_BIT - CHAR_BIT); + for (int i = 0; i < CHAR_BIT; i++) { + if (crc & (1 << (UINT32_BIT - 1))) { + crc = (crc << 1) ^ polynomial; + } else { + crc = (crc << 1); + } + } + } + crc = reverse(crc, CHAR_BIT * sizeof(crc)) ^ UINT32_MAX; - uint_least32_t crc = UINT_LEAST32_MAX; - intmax_t octets = 0; + snprintf(sum.sum, sizeof(sum.sum), "%"PRIu32, crc); + return sum; +} + +int cksum(const char *path) +{ + uintmax_t octets = 0; FILE *f = stdin; if (path && strcmp(path, "-")) { @@ -47,16 +82,9 @@ int cksum(const char *path) return 1; } - int c; - while ((c = fgetc(f)) != EOF) { - octets++; - crc ^= (unsigned char)c; - for (int k = 0; k < CHAR_BIT; k++) { - crc = crc & 1 ? (crc >> 1) ^ polynomial : crc >> 1; - } - } + struct sum sum = crc32(f); + printf("%s %"PRIuMAX"", sum.sum, sum.size); - printf("%"PRIuLEAST32" %"PRIdMAX"", crc, octets); if (f != stdin) { printf(" %s", path); fclose(f); |