Date: Tue, 26 Apr 2005 12:42:08 -0700 From: Marcel Moolenaar <marcel@xcllnt.net> To: Jose M Rodriguez <josemi@freebsd.jazztel.es> Cc: freebsd-current@freebsd.org Subject: Re: rigth crc32 implementation Message-ID: <20050426194208.GB7773@ns1.xcllnt.net> In-Reply-To: <200504261143.55195.josemi@redesjm.local> References: <200504261143.55195.josemi@redesjm.local>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Apr 26, 2005 at 11:43:54AM +0200, Jose M Rodriguez wrote: > > My first think was use the libkern based one, but I found: > sys/linkern/crc32.c > > - the code may not be endian safe. It operates on bytes, so it's endian-safe. Note that the uint32_t that's returned is not subject to endianness issues: it's always in the native byte order. The caller of crc32 needs to byteswap if it needs to compare this integral with a CRC that's not in the native byte order. > - the code lacks support for processing chuncks. This should be easy enough to add. We could add an alternative version that also takes the initial CRC value. The initial CRC value can be the calculated CRC of a previous chunk. This also solves the problem that some CRC calculations start with a CRC of 0U, while others start with a CRC of ~0U. See also: http://www.repairfaq.org/filipg/LINK/F_crc_v34.html#CRCV_003 Roughly speaking (ok, not quite) this is what needs to happen: uint32_t crc32_raw(const void *buf, size_t size, uint32_t crc) { const uint8_t *p = buf; while (size--) crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); return (crc); } uint32_t crc32(const void *buf, size_t size) { uint32_t crc; crc = crc32_raw(buf, size, ~0U); return (crc ^ ~0U); } Here, crc32_raw() allows the caller to specify the initial CRC value as well as allows the caller to handle the final XOR. Does the above solve your CRC problems? -- Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050426194208.GB7773>