wmem: allow wmem_destroy_list to ignore a NULL list.
[metze/wireshark/wip.git] / wsutil / crc16-plain.c
1 /*
2  * crc16-plain.c
3  * http://www.tty1.net/pycrc/faq_en.html#code-ownership
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 /**
13  * \file crc16-plain.c
14  * Functions and types for CRC checks.
15  *
16  * Generated on Wed Mar 18 14:12:09 2009,
17  * by pycrc v0.7, http://www.tty1.net/pycrc/
18  * using the configuration:
19  *    Width        = 16
20  *    Poly         = 0x8005
21  *    XorIn        = 0x0000
22  *    ReflectIn    = True
23  *    XorOut       = 0x0000
24  *    ReflectOut   = True
25  *    Algorithm    = table-driven
26  *    Direct       = True
27  *
28  * Modified 2009-03-16 not to include <stdint.h> as our Win32 environment
29  * appears not to have it; we're using GLib types, instead.
30  *****************************************************************************/
31 #include "wsutil/crc16-plain.h"
32 #include <stdlib.h>
33
34 /**
35  * Static table used for the table_driven implementation.
36  *****************************************************************************/
37 static const crc16_plain_t crc_table_reflected[256] = {
38     0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
39     0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
40     0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
41     0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
42     0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
43     0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
44     0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
45     0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
46     0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
47     0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
48     0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
49     0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
50     0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
51     0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
52     0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
53     0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
54     0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
55     0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
56     0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
57     0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
58     0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
59     0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
60     0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
61     0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
62     0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
63     0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
64     0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
65     0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
66     0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
67     0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
68     0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
69     0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
70 };
71
72 /**
73  * Reflect all bits of a \a data word of \a data_len bytes.
74  *
75  * \param data         The data word to be reflected.
76  * \param data_len     The width of \a data expressed in number of bits.
77  * \return     The reflected data.
78  *****************************************************************************/
79 long crc16_plain_reflect(long data, size_t data_len)
80 {
81     unsigned int i;
82     long ret;
83
84     ret = data & 0x01;
85     for (i = 1; i < data_len; i++)
86     {
87         data >>= 1;
88         ret = (ret << 1) | (data & 0x01);
89     }
90     return ret;
91 }
92
93
94 /**
95  * Update the crc value with new data.
96  *
97  * \param crc      The current crc value.
98  * \param data     Pointer to a buffer of \a data_len bytes.
99  * \param data_len Number of bytes in the \a data buffer.
100  * \return         The updated crc value.
101  *****************************************************************************/
102 crc16_plain_t crc16_plain_update(crc16_plain_t crc, const unsigned char *data, size_t data_len)
103 {
104     unsigned int tbl_idx;
105
106     while (data_len--) {
107         tbl_idx = (crc ^ *data) & 0xff;
108         crc = (crc_table_reflected[tbl_idx] ^ (crc >> 8)) & 0xffff;
109
110         data++;
111     }
112     return crc & 0xffff;
113 }
114
115 /* Generated on Tue Jul 24 09:08:46 2012,
116  * by pycrc v0.7.10, http://www.tty1.net/pycrc/
117  * using the configuration:
118  *    Width        = 16
119  *    Poly         = 0x8005
120  *    XorIn        = 0x0000
121  *    ReflectIn    = False
122  *    XorOut       = 0x0000
123  *    ReflectOut   = False
124  *    Algorithm    = table-driven
125  *****************************************************************************/
126 static const guint16 crc16_table_8005_noreflect_noxor[256] = {
127     0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
128     0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
129     0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
130     0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
131     0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
132     0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
133     0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
134     0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
135     0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
136     0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
137     0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
138     0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
139     0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
140     0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
141     0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
142     0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
143     0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
144     0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
145     0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
146     0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
147     0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
148     0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
149     0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
150     0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
151     0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
152     0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
153     0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
154     0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
155     0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
156     0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
157     0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
158     0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
159 };
160
161 /**
162  * Calculate the crc-16 (x^16 + x^15 + x^2 + 1) value for data. Note that this
163  * CRC is not equal to crc16_plain.
164  *
165  * \param data     Pointer to a buffer of \a data_len bytes.
166  * \param data_len Number of bytes in the \a data buffer.
167  * \return         The crc value.
168  *****************************************************************************/
169 guint16 crc16_8005_noreflect_noxor(const guint8 *data, guint64 data_len)
170 {
171     guint tbl_idx;
172     guint16 crc = 0;
173
174     while (data_len--) {
175         tbl_idx = ((crc >> 8) ^ *data) & 0xff;
176         crc = (crc16_table_8005_noreflect_noxor[tbl_idx] ^ (crc << 8)) & 0xffff;
177
178         data++;
179     }
180     return crc & 0xffff;
181 }
182
183 /*
184  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
185  *
186  * Local variables:
187  * c-basic-offset: 4
188  * tab-width: 8
189  * indent-tabs-mode: nil
190  * End:
191  *
192  * vi: set shiftwidth=4 tabstop=8 expandtab:
193  * :indentSize=4:tabSize=8:noTabs=true:
194  */