mirror of
https://github.com/coreutils/coreutils.git
synced 2024-11-23 01:46:48 +08:00
cksum: add support for --algorithm=crc32b
$ echo -n '123456789' | cksum --raw -a crc32b | basenc --base16 CBF43926 * bootstrap.conf: Explicitly depend on the crc module. * doc/coreutils.texi (cksum): Add "crc32b" as an argument to -a. * src/cksum.c (crc32b_sum_stream): A new function similar to crc_sum_stream, but which does not include the length in the CRC calculation. * src/cksum.h: Add crc32b_sum_stream prototype. * src/digest.c: Add "crc32b" as an argument to -a. * tests/cksum/cksum.sh: Refactor to test both crc and crc32b. * tests/cksum/cksum-a.sh: Add "crc32b" case. * tests/cksum/cksum-base64.pl: Likewise. * tests/misc/read-errors.sh: Likewise. * NEWS: Mention the new feature.
This commit is contained in:
parent
ee231019e1
commit
a94929715c
3
NEWS
3
NEWS
@ -39,6 +39,9 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
** New Features
|
||||
|
||||
cksum -a now supports the "crc32b" option, which calculates the CRC
|
||||
of the input as defined by ITU V.42, as used by gzip for example.
|
||||
|
||||
ls now supports the --sort=name option,
|
||||
to explicitly select the default operation of sorting by file name.
|
||||
|
||||
|
@ -63,6 +63,7 @@ gnulib_modules="
|
||||
config-h
|
||||
configmake
|
||||
copy-file-range
|
||||
crc
|
||||
crypto/md5
|
||||
crypto/sha1
|
||||
crypto/sha256
|
||||
|
@ -4051,7 +4051,8 @@ and the file name unless no arguments were given.
|
||||
The 32-bit CRC used is based on the polynomial used
|
||||
for CRC error checking in the ISO/IEC 8802-3:1996 standard (Ethernet).
|
||||
Similar output formats are used for the other legacy checksums
|
||||
selectable with @option{--algorithm=sysv} or @option{--algorithm=bsd},
|
||||
selectable with @option{--algorithm=crc32b}, and
|
||||
@option{--algorithm=sysv} or @option{--algorithm=bsd}
|
||||
detailed at @ref{sum invocation}.
|
||||
|
||||
@item Tagged output format
|
||||
@ -4100,6 +4101,7 @@ Supported legacy checksums (which are not supported by @option{--check}):
|
||||
@samp{sysv} equivalent to @command{sum -s}
|
||||
@samp{bsd} equivalent to @command{sum -r}
|
||||
@samp{crc} equivalent to @command{cksum} (the default)
|
||||
@samp{crc32b} only available through @command{cksum}
|
||||
@end example
|
||||
|
||||
Supported more modern digest algorithms are:
|
||||
@ -4151,7 +4153,7 @@ as the length is automatically determined when checking.
|
||||
Print only the unencoded raw binary digest for a single input.
|
||||
Do not output the file name or anything else.
|
||||
Use network byte order (big endian) where applicable:
|
||||
for @samp{bsd}, @samp{crc}, and @samp{sysv}.
|
||||
for @samp{bsd}, @samp{crc}, @samp{crc32b}, and @samp{sysv}.
|
||||
This option works only with a single input.
|
||||
Unlike other output formats, @command{cksum} provides no way to
|
||||
@option{--check} a @option{--raw} checksum.
|
||||
@ -4225,7 +4227,7 @@ a checksum inconsistent with the associated file, or if no valid
|
||||
line is found, @command{cksum} exits with nonzero status. Otherwise,
|
||||
it exits successfully.
|
||||
The @command{cksum} command does not support @option{--check}
|
||||
with the older @samp{sysv}, @samp{bsd}, or @samp{crc} algorithms.
|
||||
with the older @samp{sysv}, @samp{bsd}, @samp{crc} or @samp{crc32b} algorithms.
|
||||
|
||||
@item --ignore-missing
|
||||
@opindex --ignore-missing
|
||||
|
38
src/cksum.c
38
src/cksum.c
@ -135,6 +135,7 @@ main (void)
|
||||
#else /* !CRCTAB */
|
||||
|
||||
# include "cksum.h"
|
||||
# include "crc.h"
|
||||
|
||||
/* Number of bytes to read at once. */
|
||||
# define BUFLEN (1 << 16)
|
||||
@ -242,6 +243,43 @@ crc_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate the crc32b checksum and length in bytes of stream STREAM.
|
||||
Return -1 on error, 0 on success. */
|
||||
|
||||
int
|
||||
crc32b_sum_stream (FILE *stream, void *resstream, uintmax_t *reslen)
|
||||
{
|
||||
uint32_t buf[BUFLEN / sizeof (uint32_t)];
|
||||
uint32_t crc = 0;
|
||||
uintmax_t len = 0;
|
||||
size_t bytes_read;
|
||||
|
||||
if (!stream || !resstream || !reslen)
|
||||
return -1;
|
||||
|
||||
while ((bytes_read = fread (buf, 1, BUFLEN, stream)) > 0)
|
||||
{
|
||||
if (len + bytes_read < len)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
len += bytes_read;
|
||||
|
||||
crc = crc32_update (crc, (char const *)buf, bytes_read);
|
||||
|
||||
if (feof (stream))
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int crc_out = crc;
|
||||
memcpy (resstream, &crc_out, sizeof crc_out);
|
||||
|
||||
*reslen = len;
|
||||
|
||||
return ferror (stream) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Print the checksum and size to stdout.
|
||||
If ARGS is true, also print the FILE name. */
|
||||
|
||||
|
@ -6,6 +6,9 @@ extern bool cksum_debug;
|
||||
extern int
|
||||
crc_sum_stream (FILE *stream, void *resstream, uintmax_t *length);
|
||||
|
||||
extern int
|
||||
crc32b_sum_stream (FILE *stream, void *resstream, uintmax_t *length);
|
||||
|
||||
extern void
|
||||
output_crc (char const *file, int binary_file, void const *digest, bool raw,
|
||||
bool tagged, unsigned char delim, bool args, uintmax_t length)
|
||||
|
18
src/digest.c
18
src/digest.c
@ -290,6 +290,7 @@ enum Algorithm
|
||||
bsd,
|
||||
sysv,
|
||||
crc,
|
||||
crc32b,
|
||||
md5,
|
||||
sha1,
|
||||
sha224,
|
||||
@ -302,24 +303,24 @@ enum Algorithm
|
||||
|
||||
static char const *const algorithm_args[] =
|
||||
{
|
||||
"bsd", "sysv", "crc", "md5", "sha1", "sha224",
|
||||
"bsd", "sysv", "crc", "crc32b", "md5", "sha1", "sha224",
|
||||
"sha256", "sha384", "sha512", "blake2b", "sm3", nullptr
|
||||
};
|
||||
static enum Algorithm const algorithm_types[] =
|
||||
{
|
||||
bsd, sysv, crc, md5, sha1, sha224,
|
||||
bsd, sysv, crc, crc32b, md5, sha1, sha224,
|
||||
sha256, sha384, sha512, blake2b, sm3,
|
||||
};
|
||||
ARGMATCH_VERIFY (algorithm_args, algorithm_types);
|
||||
|
||||
static char const *const algorithm_tags[] =
|
||||
{
|
||||
"BSD", "SYSV", "CRC", "MD5", "SHA1", "SHA224",
|
||||
"BSD", "SYSV", "CRC", "CRC32B", "MD5", "SHA1", "SHA224",
|
||||
"SHA256", "SHA384", "SHA512", "BLAKE2b", "SM3", nullptr
|
||||
};
|
||||
static int const algorithm_bits[] =
|
||||
{
|
||||
16, 16, 32, 128, 160, 224,
|
||||
16, 16, 32, 32, 128, 160, 224,
|
||||
256, 384, 512, 512, 256, 0
|
||||
};
|
||||
|
||||
@ -333,6 +334,7 @@ static sumfn cksumfns[]=
|
||||
bsd_sum_stream,
|
||||
sysv_sum_stream,
|
||||
crc_sum_stream,
|
||||
crc32b_sum_stream,
|
||||
md5_sum_stream,
|
||||
sha1_sum_stream,
|
||||
sha224_sum_stream,
|
||||
@ -347,6 +349,7 @@ static digest_output_fn cksum_output_fns[]=
|
||||
output_bsd,
|
||||
output_sysv,
|
||||
output_crc,
|
||||
output_crc,
|
||||
output_file,
|
||||
output_file,
|
||||
output_file,
|
||||
@ -530,6 +533,7 @@ DIGEST determines the digest algorithm and default output format:\n\
|
||||
sysv (equivalent to sum -s)\n\
|
||||
bsd (equivalent to sum -r)\n\
|
||||
crc (equivalent to cksum)\n\
|
||||
crc32b (only available through cksum)\n\
|
||||
md5 (equivalent to md5sum)\n\
|
||||
sha1 (equivalent to sha1sum)\n\
|
||||
sha224 (equivalent to sha224sum)\n\
|
||||
@ -790,7 +794,7 @@ split_3 (char *s, size_t s_len,
|
||||
ptrdiff_t algo_tag = algorithm_from_tag (s + i);
|
||||
if (algo_tag >= 0)
|
||||
{
|
||||
if (algo_tag <= crc)
|
||||
if (algo_tag <= crc32b)
|
||||
return false; /* We don't support checking these older formats. */
|
||||
cksum_algorithm = algo_tag;
|
||||
}
|
||||
@ -1506,9 +1510,11 @@ main (int argc, char **argv)
|
||||
case bsd:
|
||||
case sysv:
|
||||
case crc:
|
||||
case crc32b:
|
||||
if (do_check && algorithm_specified)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("--check is not supported with --algorithm={bsd,sysv,crc}"));
|
||||
_("--check is not supported with "
|
||||
"--algorithm={bsd,sysv,crc,crc32b}"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -44,6 +44,7 @@ while read algo prog mode; do
|
||||
bsd) ;;
|
||||
sysv) ;;
|
||||
crc) ;;
|
||||
crc32b) ;;
|
||||
*) cksum --check --algorithm=$algo out-c || fail=1 ;;
|
||||
esac
|
||||
|
||||
|
@ -29,6 +29,7 @@ my @pairs =
|
||||
['sysv', "0 0 f"],
|
||||
['bsd', "00000 0 f"],
|
||||
['crc', "4294967295 0 f"],
|
||||
['crc32b', "0 0 f"],
|
||||
['md5', "1B2M2Y8AsgTpgAmY7PhCfg=="],
|
||||
['sha1', "2jmj7l5rSw0yVb/vlWAYkK/YBwk="],
|
||||
['sha224', "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw=="],
|
||||
@ -43,7 +44,7 @@ my @pairs =
|
||||
# Use the hard-coded "f" as file name.
|
||||
sub fmt ($$) {
|
||||
my ($h, $v) = @_;
|
||||
$h !~ m{^(sysv|bsd|crc)$} and $v = uc($h). " (f) = $v";
|
||||
$h !~ m{^(sysv|bsd|crc|crc32b)$} and $v = uc($h). " (f) = $v";
|
||||
# BLAKE2b is inconsistent:
|
||||
$v =~ s{BLAKE2B}{BLAKE2b};
|
||||
return "$v"
|
||||
@ -59,7 +60,7 @@ my @Tests =
|
||||
(map {my ($h,$v)= @$_; my $o=fmt $h,$v;
|
||||
["chk-".$h, "--check --strict", {IN=>$o},
|
||||
{AUX=>{f=>''}}, {OUT=>"f: OK\n"}]}
|
||||
grep { $_->[0] !~ m{^(sysv|bsd|crc)$} } @pairs),
|
||||
grep { $_->[0] !~ m{^(sysv|bsd|crc|crc32b)$} } @pairs),
|
||||
|
||||
# For digests ending in "=", ensure --check fails if any "=" is removed.
|
||||
(map {my ($h,$v)= @$_; my $o=fmt $h,$v;
|
||||
|
@ -19,56 +19,57 @@
|
||||
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
print_ver_ cksum printf
|
||||
|
||||
|
||||
returns_ 1 cksum missing || fail=1
|
||||
|
||||
# Pass in expected crc and crc32b for file "in"
|
||||
# Sets fail=1 upon failure
|
||||
crc_check() {
|
||||
for crct in crc crc32b; do
|
||||
cksum -a $crct in > out || fail=1
|
||||
case "$crct" in crc) crce="$1";; crc32b) crce="$2";; esac
|
||||
size=$(stat -c %s in) || framework_failure_
|
||||
printf '%s\n' "$crce $size in" > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Check complete range of bytes
|
||||
{
|
||||
for offset in $(seq -1 6); do
|
||||
env printf $(env printf '\\%03o' $(seq 0 $offset));
|
||||
env printf $(env printf '\\%03o' $(seq 0 255));
|
||||
done
|
||||
} > in || framework_failure_
|
||||
|
||||
cksum in > out || fail=1
|
||||
printf '%s\n' '4097727897 2077 in' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
crc_check 4097727897 559400337
|
||||
|
||||
# Make sure crc is correct for files larger than 128 bytes (4 fold pclmul)
|
||||
{
|
||||
env printf $(env printf '\\%03o' $(seq 0 130));
|
||||
} > in || framework_failure_
|
||||
|
||||
cksum in > out || fail=1
|
||||
printf '%s\n' '3800919234 131 in' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
crc_check 3800919234 3739179551
|
||||
|
||||
# Make sure crc is correct for files larger than 32 bytes
|
||||
# but <128 bytes (1 fold pclmul)
|
||||
{
|
||||
env printf $(env printf '\\%03o' $(seq 0 64));
|
||||
} > in || framework_failure_
|
||||
|
||||
cksum in > out || fail=1
|
||||
printf '%s\n' '796287823 65 in' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
crc_check 796287823 1086353368
|
||||
|
||||
# Make sure crc is still handled correctly when next 65k buffer is read
|
||||
# (>32 bytes more than 65k)
|
||||
{
|
||||
seq 1 12780
|
||||
} > in || framework_failure_
|
||||
|
||||
cksum in > out || fail=1
|
||||
printf '%s\n' '3720986905 65574 in' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
crc_check 3720986905 388883562
|
||||
|
||||
# Make sure crc is still handled correctly when next 65k buffer is read
|
||||
# (>=128 bytes more than 65k)
|
||||
{
|
||||
seq 1 12795
|
||||
} > in || framework_failure_
|
||||
crc_check 4278270357 2796628507
|
||||
|
||||
cksum in > out || fail=1
|
||||
printf '%s\n' '4278270357 65664 in' > exp || framework_failure_
|
||||
compare exp out || fail=1
|
||||
|
||||
Exit $fail
|
||||
|
@ -27,6 +27,7 @@ cat .
|
||||
cksum -a blake2b .
|
||||
cksum -a bsd .
|
||||
cksum -a crc .
|
||||
cksum -a crc32b .
|
||||
cksum -a md5 .
|
||||
cksum -a sha1 .
|
||||
cksum -a sha224 .
|
||||
|
Loading…
Reference in New Issue
Block a user