summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-08-05 13:13:46 -0400
committerJakob Kaivo <jkk@ung.org>2019-08-05 13:13:46 -0400
commit260e33f13acbdd2bbedf97a2c5e567bdc099d6dc (patch)
tree7215cb4741486aa002014e7d5722ee754f0b61ab
parent43e57e561231c8b9b7a5fc5aeed8c820b344b4c1 (diff)
try to implement
-rw-r--r--cksum.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/cksum.c b/cksum.c
index 35d373a..18f0f1a 100644
--- a/cksum.c
+++ b/cksum.c
@@ -17,18 +17,24 @@
*
*/
-#define _XOPEN_SOURCE 700
+#define _POSIX_C_SOURCE 2
+#include <errno.h>
#include <inttypes.h>
+#include <limits.h>
+#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-/* G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 */
-const uint64_t polynomial = UINT64_C(0x104C11DB7);
+/* TODO: study http://ross.net/crc/download/crc_v3.txt */
int cksum(const char *path)
{
- uint64_t checksum = 0;
+ const uint_least32_t polynomial =
+ /* 0x04c11db7; */ /* x^32 is implicit */
+ 0x82608edb; /* +1 is implicit */
+
+ uint_least32_t crc = UINT_LEAST32_MAX;
intmax_t octets = 0;
FILE *f = stdin;
@@ -37,34 +43,40 @@ int cksum(const char *path)
}
if (f == NULL) {
+ fprintf(stderr, "cksum: %s: %s\n", path, strerror(errno));
return 1;
}
- while (!feof(f)) {
- uint64_t next = 0;
- octets += fread(&next, sizeof(next), 1, f);
- checksum ^= next;
+ 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;
+ }
}
+ printf("%"PRIuLEAST32" %"PRIdMAX"", crc, octets);
if (f != stdin) {
+ printf(" %s", path);
fclose(f);
}
+ putchar('\n');
- printf("%"PRIu64" %"PRIdMAX" %s\n", checksum, octets, path);
return 0;
}
int main(int argc, char *argv[])
{
+ setlocale(LC_ALL, "");
+
while (getopt(argc, argv, "") != -1) {
return 1;
}
int r = 0;
-
do {
r |= cksum(argv[optind++]);
} while (optind < argc);
-
- return 0;
+ return r;
}