summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-11-21 14:50:39 -0500
committerJakob Kaivo <jkk@ung.org>2019-11-21 14:50:39 -0500
commitc02867e0a3368e58248d6f59b4d0b9806a7216c5 (patch)
tree9ce0f1d259300728c3dd3e9c26394cb4be890cd5
parent260e33f13acbdd2bbedf97a2c5e567bdc099d6dc (diff)
working
-rw-r--r--cksum.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/cksum.c b/cksum.c
index 18f0f1a..7eacb6e 100644
--- a/cksum.c
+++ b/cksum.c
@@ -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);