Options "--init-with-zero" and "--negate-final" have been implemented.

This commit is contained in:
LoRd_MuldeR 2022-09-12 21:42:12 +02:00
parent 1fb3709fa7
commit 078cda1a31
4 changed files with 84 additions and 35 deletions

View File

@ -5,7 +5,7 @@ STRIP ?= 1
ifneq (,$(firstword $(filter x86_64-%,$(MACHINE)))) ifneq (,$(firstword $(filter x86_64-%,$(MACHINE))))
MARCH ?= x86-64 MARCH ?= x86-64
MTUNE ?= nocona MTUNE ?= znver3
else else
ifneq (,$(firstword $(filter i686-%,$(MACHINE)))) ifneq (,$(firstword $(filter i686-%,$(MACHINE))))
MARCH ?= i586 MARCH ?= i586
@ -13,7 +13,7 @@ else
endif endif
endif endif
CFLAGS = -Wall -std=gnu99 -O3 -DNDEBUG CFLAGS = -Wall -std=gnu99 -Ofast -DNDEBUG
ifneq (,$(XCFLAGS)) ifneq (,$(XCFLAGS))
CFLAGS += $(XCFLAGS) CFLAGS += $(XCFLAGS)

14
README
View File

@ -1,14 +0,0 @@
CRC64
-----
Synopsis:
crc64.exe [OPTIONS] [<file_1> [<file_2> ... <file_n>]]
Options:
--help --version Print help screen / show version information
--binary Output the digest in binary format (default is hex-format)
--decimal Output the digest in decimal string format
--upper-case Print hex-string in upper-case letters (default is lower-case)
--no-padding Print the digest *without* any leading zeros
--silent Suppress error messages
--ignore-errors Ignore I/O errors and proceeed with the next file

26
README.md Normal file
View File

@ -0,0 +1,26 @@
CRC-64
======
Simple cross-platform command-line tool for computing CRC-64 checksums.
```
Synopsis:
crc64.exe [OPTIONS] [<file_1> [<file_2> ... <file_n>]]
Options:
--help --version Print help screen / show version information
--binary Output the digest in binary format (default is hex-format)
--decimal Output the digest in decimal string format
--upper-case Print hex-string as upper-case (default is lower-case)
--no-padding Print the digest *without* any leading zeros
--silent Suppress error messages
--ignore-errors Ignore I/O errors and proceeed with the next file
--no-flush Do *not* flush the standard output stream after each file
--init-with-zero Initialize CRC with zero (default is 0xFFF...FFF)
--negate-final Negate the final CRC result
```
One output line is generated per input file:
```
<CRC64-Checksum>[SP]<File-Size>[SP]<File-Name>[LF]
```

75
crc64.c
View File

@ -22,16 +22,40 @@
static const int VERSION_MAJOR = 1; static const int VERSION_MAJOR = 1;
static const int VERSION_MINOR = 0; static const int VERSION_MINOR = 0;
static const int VERSION_PATCH = 1; static const int VERSION_PATCH = 2;
#define OPT_HELPSC 0x01 #define OPT_HELPSC 0x001
#define OPT_BINARY 0x02 #define OPT_BINARY 0x002
#define OPT_UPPERC 0x04 #define OPT_UPPERC 0x004
#define OPT_DECIML 0x08 #define OPT_DECIML 0x008
#define OPT_NOPADD 0x10 #define OPT_NOPADD 0x010
#define OPT_IGNERR 0x20 #define OPT_IGNERR 0x020
#define OPT_SILENT 0x40 #define OPT_SILENT 0x040
#define OPT_NOFLSH 0x80 #define OPT_NOFLSH 0x080
#define OPT_NEGATE 0x100
#define OPT_ZEROIN 0x200
/* ======================================================================== */
/* Compiler */
/* ======================================================================== */
#if defined(__GNUC__) || defined(__INTEL_LLVM_COMPILER)
#define ALIGNED(X) __attribute__((aligned(X)))
#define PURE __attribute__((pure))
#define FORCE_INLINE __attribute__((always_inline)) __inline__
#elif defined(_MSC_VER)
#define ALIGNED(X) __declspec(align(X))
#define PURE
#define FORCE_INLINE __forceinline
#else
#error Unsupported compiler, please fix !!!
#endif
/* ======================================================================== */ /* ======================================================================== */
/* Platform */ /* Platform */
@ -92,7 +116,7 @@ static void sigint_handler(const int sig)
static const uint64_t CRC64_INITIALIZER = UINT64_C(~0); static const uint64_t CRC64_INITIALIZER = UINT64_C(~0);
static const uint64_t CRC64_TABLE[256] = static const uint64_t ALIGNED(64) CRC64_TABLE[256] =
{ {
0x0000000000000000ULL, 0x42f0e1eba9ea3693ULL, 0x85e1c3d753d46d26ULL, 0xc711223cfa3e5bb5ULL, 0x0000000000000000ULL, 0x42f0e1eba9ea3693ULL, 0x85e1c3d753d46d26ULL, 0xc711223cfa3e5bb5ULL,
0x493366450e42ecdfULL, 0x0bc387aea7a8da4cULL, 0xccd2a5925d9681f9ULL, 0x8e224479f47cb76aULL, 0x493366450e42ecdfULL, 0x0bc387aea7a8da4cULL, 0xccd2a5925d9681f9ULL, 0x8e224479f47cb76aULL,
@ -160,14 +184,12 @@ static const uint64_t CRC64_TABLE[256] =
0x5dedc41a34bbeeb2ULL, 0x1f1d25f19d51d821ULL, 0xd80c07cd676f8394ULL, 0x9afce626ce85b507ULL 0x5dedc41a34bbeeb2ULL, 0x1f1d25f19d51d821ULL, 0xd80c07cd676f8394ULL, 0x9afce626ce85b507ULL
}; };
static uint64_t crc64_update(uint64_t crc, const uint8_t *const buffer, const size_t count) static uint64_t PURE FORCE_INLINE crc64_update(uint64_t crc, const uint8_t *ptr, const size_t count)
{ {
const uint8_t *p = buffer; const uint8_t *const endptr = ptr + count;
size_t i, t; while (ptr < endptr)
for (i = 0U; i < count; ++i)
{ {
t = ((crc >> 56) ^ (*p++)) & 0xFF; crc = CRC64_TABLE[((crc >> 56) ^ (*ptr++)) & 0xFF] ^ (crc << 8);
crc = CRC64_TABLE[t] ^ (crc << 8);
} }
return crc; return crc;
} }
@ -211,7 +233,7 @@ static int process(const CHAR *const file_name, const int options)
{ {
int retval = EXIT_FAILURE; int retval = EXIT_FAILURE;
FILE *input = NULL; FILE *input = NULL;
uint64_t crc = CRC64_INITIALIZER, total_size = 0U; uint64_t crc = (!(options & OPT_ZEROIN)) ? CRC64_INITIALIZER : UINT64_C(0), total_size = 0U;
uint8_t buffer[BUFF_SIZE]; uint8_t buffer[BUFF_SIZE];
input = file_name ? FOPEN(file_name, T("rb")) : stdin; input = file_name ? FOPEN(file_name, T("rb")) : stdin;
@ -259,6 +281,11 @@ static int process(const CHAR *const file_name, const int options)
} }
} }
if (options & OPT_NEGATE)
{
crc = ~crc;
}
if (!(options & OPT_BINARY)) if (!(options & OPT_BINARY))
{ {
if (!(options & OPT_DECIML)) if (!(options & OPT_DECIML))
@ -378,6 +405,14 @@ int MAIN(int argc, CHAR *argv[])
{ {
options |= OPT_NOFLSH; options |= OPT_NOFLSH;
} }
else if (!STRCASECMP(arg_val, T("init-with-zero")))
{
options |= OPT_ZEROIN;
}
else if (!STRCASECMP(arg_val, T("negate-final")))
{
options |= OPT_NEGATE;
}
else else
{ {
FPRINTF(stderr, T("Option \"--%s\" is not recognized!\n"), arg_val); FPRINTF(stderr, T("Option \"--%s\" is not recognized!\n"), arg_val);
@ -405,11 +440,13 @@ int MAIN(int argc, CHAR *argv[])
FPUTS(T(" --help --version Print help screen / show version information\n"), stderr); FPUTS(T(" --help --version Print help screen / show version information\n"), stderr);
FPUTS(T(" --binary Output the digest in binary format (default is hex-format)\n"), stderr); FPUTS(T(" --binary Output the digest in binary format (default is hex-format)\n"), stderr);
FPUTS(T(" --decimal Output the digest in decimal string format\n"), stderr); FPUTS(T(" --decimal Output the digest in decimal string format\n"), stderr);
FPUTS(T(" --upper-case Print hex-string in upper-case letters (default is lower-case)\n"), stderr); FPUTS(T(" --upper-case Print hex-string as upper-case (default is lower-case)\n"), stderr);
FPUTS(T(" --no-padding Print the digest *without* any leading zeros\n"), stderr); FPUTS(T(" --no-padding Print the digest *without* any leading zeros\n"), stderr);
FPUTS(T(" --silent Suppress error messages\n"), stderr); FPUTS(T(" --silent Suppress error messages\n"), stderr);
FPUTS(T(" --ignore-errors Ignore I/O errors and proceeed with the next file\n"), stderr); FPUTS(T(" --ignore-errors Ignore I/O errors and proceeed with the next file\n"), stderr);
FPUTS(T(" --no-flush Do *not* flush the standard output stream after each file\n\n"), stderr); FPUTS(T(" --no-flush Do *not* flush the standard output stream after each file\n"), stderr);
FPUTS(T(" --init-with-zero Initialize CRC with zero (default is 0xFFF...FFF)\n"), stderr);
FPUTS(T(" --negate-final Negate the final CRC result\n\n"), stderr);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }