From owner-freebsd-current@FreeBSD.ORG Tue Apr 26 19:42:11 2005 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A2BF716A4CE for ; Tue, 26 Apr 2005 19:42:11 +0000 (GMT) Received: from ns1.xcllnt.net (209-128-86-226.bayarea.net [209.128.86.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id 596CA43D60 for ; Tue, 26 Apr 2005 19:42:11 +0000 (GMT) (envelope-from marcel@xcllnt.net) Received: from ns1.xcllnt.net (localhost [127.0.0.1]) by ns1.xcllnt.net (8.13.3/8.13.3) with ESMTP id j3QJg8en007960; Tue, 26 Apr 2005 12:42:09 -0700 (PDT) (envelope-from marcel@ns1.xcllnt.net) Received: (from marcel@localhost) by ns1.xcllnt.net (8.13.3/8.13.3/Submit) id j3QJg8Uf007959; Tue, 26 Apr 2005 12:42:08 -0700 (PDT) (envelope-from marcel) Date: Tue, 26 Apr 2005 12:42:08 -0700 From: Marcel Moolenaar To: Jose M Rodriguez Message-ID: <20050426194208.GB7773@ns1.xcllnt.net> References: <200504261143.55195.josemi@redesjm.local> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200504261143.55195.josemi@redesjm.local> User-Agent: Mutt/1.4.2.1i cc: freebsd-current@freebsd.org Subject: Re: rigth crc32 implementation X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Apr 2005 19:42:11 -0000 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