#!/usr/local/bin/perl eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' if 0; # not running under some shell # # An implementation of the 'cksum' utility in Perl. Written for the Perl # Power Tools (PPT) project by Theo Van Dinter (felicity@kluge.net). # # $Id: sum,v 1.1.1.1 2001/06/06 08:55:12 sdague Exp $ # use integer; use Getopt::Std; use strict; use vars qw($opt_h $opt_o); &help unless getopts('ho:'); &help if ( $opt_h ); # default to bsd unless spec. $opt_o = 1 unless ( $0 =~ /cksum$/ || defined($opt_o) ); @ARGV = ( "-" ) unless ( @ARGV ); # STDIN if no files specified. # returns 1 on file read error, 0 if all ok. my($exitval) = 0; # return value foreach (@ARGV) { open(IN,$_) || die "Can't open file for reading:$!"; my($rval,$crc,$len)= ($opt_o==0)?&crc32(\*IN):($opt_o==1)?&sum1(\*IN):&sum2(\*IN); unless ( defined($rval) && ($rval == 0) ) { warn "$0: $_: $!\n"; $exitval = 1; next; } # Display output information printf "%lu %lu%s\n",$crc,$len,($_ eq "-")?"":" $_"; close(IN); } exit $exitval; sub sum1 { my($fh) = shift; my($crc) = my($len) = 0; my($buf,$num,$i); my($buflen) = 4096; # buffer is "4k", you can up it if you want... while($num = sysread $fh, $buf, $buflen) { for($len = ($len+$num), $i = 0; $i<$num; $i++) { $crc |= 0x10000 if ( $crc & 1 ); # get ready for rotating the 1 below $crc = (($crc>>1)+ord(substr $buf, $i, 1)) & 0xffff; # keep to 16-bit } } return $num,$crc,($len+1023)/1024; # round # of blocks up ... } sub sum2 { my($fh) = shift; my($crc) = my($len) = 0; my($buf,$num,$i); my($buflen) = 4096; # buffer is "4k", you can up it if you want... while($num = sysread $fh, $buf, $buflen) { $len += $num; $crc += unpack("%32C*", $buf); } # crc = s (total of bytes) $crc = ($crc & 0xffff) + ($crc & 0xffffffff) / 0x10000; # r $crc = ($crc & 0xffff) + ($crc / 0x10000); # cksum return $num,$crc,($len+511)/512; # round # of blocks up ... } # does a bunch of ands to keep the answers within 32-bits sub crc32 { my($fh) = shift; my($crc) = my($len) = 0; my($buf,$num,$i); my($buflen) = 4096; # buffer is "4k", you can up it if you want... # crctable/crc32 alg converted from openbsd's cksum program ... my(@crctable) = ( 0x0, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 ); while($num = sysread $fh, $buf, $buflen) { for($len = ($len+$num)&0xffffffff, $i = 0; $i<$num; $i++) { $crc = ($crc << 8 ^ $crctable[$crc >> 24 ^ ord(substr $buf, $i, 1)]) & 0xffffffff; } } my($rlen) = $len; # for reporting ... for(;$len!=0;$len>>=8) { # MSB first $crc = (($crc << 8) ^ $crctable[($crc >> 24) ^ ($len&0xff)]) & 0xffffffff; } return $num,~$crc,$rlen; } sub help { print " usage: $0 [-o 0|1|2] [-h] [file ...] -o Specifies algorithm to use ... 0 is CRC32 (default), 1 is BSD Algorithm 1, 2 is SYSV Algorithm 2. -h Help! (this display) Note: If this program is launched with a name other than 'cksum', the default of BSD Algorithm 1 is used unless otherwise specified via switch. "; exit 0; } =head1 NAME sum - display file checksums and block counts =head1 SYNOPSIS B [ B<-o> I<0|1|2> ] [ B<-h> ] [ I ] =head1 DESCRIPTION sum outputs three space seperated values: file CRC, file size, and file name. Can be used to find errors in transmitted files. You should not use sum for security checks as they are easily fooled. Look into md5sum for something a bit more secure. If no file names are specified, stdin is used and no file name will displayed in the output. =head1 OPTIONS AND ARGUMENTS =item I<-h> Display the usage help message. =item I<-o> Specify the output type for file CRC and size. C<0>--CRC is computed using the CRC 32 algorithm, the default unless otherwise specified. Output size is in bytes. C<1>--CRC is computed using BSD Historic Algorithm 1 (16-bit checksum with right rotation between byte addition). Output size is number of 1024 byte blocks. C<2>--CRC is computed using SYSV Historic Algorithm 2 (32-bit checksum). Output size is number of 512 byte blocks. =head1 NOTES sum returns 0 on success or 1 if an error occurred. The program checks the name in which it was called. If it is anything except "cksum", the output will default to BSD Historic Algorithm 1 unless otherwise specified. Otherwise, the default is CRC32 mode. Algorithms 1 and 2 will round up to the next block count for partial blocks. CRC 32 algorithm ported directly from OpenBSD cksum C source code. =head1 HISTORY Perl version rewritten for the Perl Power Tools project from the description of the cksum program in OpenBSD. =head1 AUTHOR Theo Van Dinter (felicity@kluge.net) =head1 SEE ALSO md5sum(1)