aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_crc.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-05-29 00:46:26 +0000
committerChristian Grothoff <christian@grothoff.org>2009-05-29 00:46:26 +0000
commit0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9 (patch)
tree6b552f40eb089db96409a312a98d9b12bd669102 /src/util/crypto_crc.c
downloadgnunet-0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9.tar.gz
gnunet-0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9.zip
ng
Diffstat (limited to 'src/util/crypto_crc.c')
-rw-r--r--src/util/crypto_crc.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c
new file mode 100644
index 000000000..35d1e2576
--- /dev/null
+++ b/src/util/crypto_crc.c
@@ -0,0 +1,106 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19
20 For the actual CRC code:
21 Copyright abandoned; this code is in the public domain.
22 Provided to GNUnet by peter@horizon.com
23*/
24
25/**
26 * @file util/crypto_crc.c
27 * @brief implementation of CRC32
28 * @author Christian Grothoff
29 */
30
31#include "platform.h"
32#include "gnunet_common.h"
33#include "gnunet_crypto_lib.h"
34
35/* Avoid wasting space on 8-byte longs. */
36#if UINT_MAX >= 0xffffffff
37typedef unsigned int uLong;
38#elif ULONG_MAX >= 0xffffffff
39typedef unsigned long uLong;
40#else
41#error This compiler is not ANSI-compliant!
42#endif
43
44#define Z_NULL 0
45
46
47#define POLYNOMIAL (uLong)0xedb88320
48static uLong crc_table[256];
49
50/*
51 * This routine writes each crc_table entry exactly once,
52 * with the ccorrect final value. Thus, it is safe to call
53 * even on a table that someone else is using concurrently.
54 */
55void __attribute__ ((constructor)) GNUNET_CRYPTO_crc_init ()
56{
57 unsigned int i, j;
58 uLong h = 1;
59 crc_table[0] = 0;
60 for (i = 128; i; i >>= 1)
61 {
62 h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0);
63 /* h is now crc_table[i] */
64 for (j = 0; j < 256; j += 2 * i)
65 crc_table[i + j] = crc_table[j] ^ h;
66 }
67}
68
69/*
70 * This computes the standard preset and inverted CRC, as used
71 * by most networking standards. Start by passing in an initial
72 * chaining value of 0, and then pass in the return value from the
73 * previous crc32() call. The final return value is the CRC.
74 * Note that this is a little-endian CRC, which is best used with
75 * data transmitted lsbit-first, and it should, itself, be appended
76 * to data in little-endian byte and bit order to preserve the
77 * property of detecting all burst errors of length 32 bits or less.
78 */
79static uLong
80crc32 (uLong crc, const char *buf, size_t len)
81{
82 GNUNET_assert (crc_table[255] != 0);
83 crc ^= 0xffffffff;
84 while (len--)
85 crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
86 return crc ^ 0xffffffff;
87}
88
89
90/**
91 * Compute the CRC32 checksum for the first len bytes of the buffer.
92 *
93 * @param buf the data over which we're taking the CRC
94 * @param len the length of the buffer
95 * @return the resulting CRC32 checksum
96 */
97int
98GNUNET_CRYPTO_crc32_n (const void *buf, unsigned int len)
99{
100 uLong crc;
101 crc = crc32 (0L, Z_NULL, 0);
102 crc = crc32 (crc, (char *) buf, len);
103 return crc;
104}
105
106/* end of crc32.c */