rax-radix-tree 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,488 @@
1
+ # Rax, an ANSI C radix tree implementation
2
+
3
+ Rax is a radix tree implementation initially written to be used in a specific
4
+ place of Redis in order to solve a performance problem, but immediately
5
+ converted into a stand alone project to make it reusable for Redis itself, outside the initial intended application, and for other projects as well.
6
+
7
+ The primary goal was to find a suitable balance between performances
8
+ and memory usage, while providing a fully featured implementation of radix trees
9
+ that can cope with many different requirements.
10
+
11
+ During the development of this library, while getting more and more excited
12
+ about how practical and applicable radix trees are, I was very surprised to
13
+ see how hard it is to write a robust implementation, especially of a fully
14
+ featured radix tree with a flexible iterator. A lot of things can go wrong
15
+ in node splitting, merging, and various edge cases. For this reason a major
16
+ goal of the project is to provide a stable and battle tested implementation
17
+ for people to use and in order to share bug fixes. The project relies a lot
18
+ on fuzz testing techniques in order to explore not just all the lines of code
19
+ the project is composed of, but a large amount of possible states.
20
+
21
+ Rax is an open source project, released under the BSD two clause license.
22
+
23
+ Major features:
24
+
25
+ * Memory conscious:
26
+ + Packed nodes representation.
27
+ + Able to avoid storing a NULL pointer inside the node if the key is set to NULL (there is an `isnull` bit in the node header).
28
+ + Lack of parent node reference. A stack is used instead when needed.
29
+ * Fast lookups:
30
+ + Edges are stored as arrays of bytes directly in the parent node, no need to access non useful children while trying to find a match. This translates into less cache misses compared to other implementations.
31
+ + Cache line friendly scanning of the correct child by storing edges as two separated arrays: an array of edge chars and one of edge pointers.
32
+ * Complete implementation:
33
+ + Deletion with nodes re-compression as needed.
34
+ + Iterators (including a way to use iterators while the tree is modified).
35
+ + Random walk iteration.
36
+ + Ability to report and resist out of memory: if malloc() returns NULL the API can report an out of memory error and always leave the tree in a consistent state.
37
+ * Readable and fixable implementation:
38
+ + All complex parts are commented with algorithms details.
39
+ + Debugging messages can be enabled to understand what the implementation is doing when calling a given function.
40
+ + Ability to print the radix tree nodes representation as ASCII art.
41
+ * Portable implementation:
42
+ + Never does unaligned accesses to memory.
43
+ + Written in ANSI C99, no extensions used.
44
+ * Extensive code and possible states test coverage using fuzz testing.
45
+ + Testing relies a lot on fuzzing in order to explore non trivial states.
46
+ + Implementation of the dictionary and iterator compared with behavior-equivalent implementations of simple hash tables and sorted arrays, generating random data and checking if the two implementations results match.
47
+ + Out of memory condition tests. The implementation is fuzzed with a special allocator returning `NULL` at random. The resulting radix tree is tested for consistency. Redis, the primary target of this implementation, does not use this feature, but the ability to handle OOM may make this implementation useful where the ability to survive OOMs is needed.
48
+ + Part of Redis: the implementation is stressed significantly in the real world.
49
+
50
+ The layout of a node is as follows. In the example, a node which represents
51
+ a key (so has a data pointer associated), has three children `x`, `y`, `z`.
52
+ Every space represents a byte in the diagram.
53
+
54
+ +----+---+--------+--------+--------+--------+
55
+ |HDR |xyz| x-ptr | y-ptr | z-ptr |dataptr |
56
+ +----+---+--------+--------+--------+--------+
57
+
58
+ The header `HDR` is actually a bitfield with the following fields:
59
+
60
+ uint32_t iskey:1; /* Does this node contain a key? */
61
+ uint32_t isnull:1; /* Associated value is NULL (don't store it). */
62
+ uint32_t iscompr:1; /* Node is compressed. */
63
+ uint32_t size:29; /* Number of children, or compressed string len. */
64
+
65
+ Compressed nodes represent chains of nodes that are not keys and have
66
+ exactly a single child, so instead of storing:
67
+
68
+ A -> B -> C -> [some other node]
69
+
70
+ We store a compressed node in the form:
71
+
72
+ "ABC" -> [some other node]
73
+
74
+ The layout of a compressed node is:
75
+
76
+ +----+---+--------+
77
+ |HDR |ABC|chld-ptr|
78
+ +----+---+--------+
79
+
80
+ # Basic API
81
+
82
+ The basic API is a trivial dictionary where you can add or remove elements.
83
+ The only notable difference is that the insert and remove APIs also accept
84
+ an optional argument in order to return, by reference, the old value stored
85
+ at a key when it is updated (on insert) or removed.
86
+
87
+ ## Creating a radix tree and adding a key
88
+
89
+ A new radix tree is created with:
90
+
91
+ rax *rt = raxNew();
92
+
93
+ In order to insert a new key, the following function is used:
94
+
95
+ int raxInsert(rax *rax, unsigned char *s, size_t len, void *data,
96
+ void **old);
97
+
98
+ Example usage:
99
+
100
+ raxInsert(rt,(unsigned char*)"mykey",5,some_void_value,NULL);
101
+
102
+ The function returns 1 if the key was inserted correctly, or 0 if the key
103
+ was already in the radix tree: in this case, the value is updated. The
104
+ value of 0 is also returned on out of memory, however in that case
105
+ `errno` is set to `ENOMEM`.
106
+
107
+ If the associated value `data` is NULL, the node where the key
108
+ is stored does not use additional memory to store the NULL value, so
109
+ dictionaries composed of just keys are memory efficient if you use
110
+ NULL as associated value.
111
+
112
+ Note that keys are unsigned arrays of chars and you need to specify the
113
+ length: Rax is binary safe, so the key can be anything.
114
+
115
+ The insertion function is also available in a variant that will not
116
+ overwrite the existing key value if any:
117
+
118
+ int raxTryInsert(rax *rax, unsigned char *s, size_t len, void *data,
119
+ void **old);
120
+
121
+ The function is exactly the same as raxInsert(), however if the key
122
+ exists the function returns 0 (like raxInsert) without touching the
123
+ old value. The old value can be still returned via the 'old' pointer
124
+ by reference.
125
+
126
+ ## Key lookup
127
+
128
+ The lookup function is the following:
129
+
130
+ void *raxFind(rax *rax, unsigned char *s, size_t len);
131
+
132
+ This function returns the special value `raxNotFound` if the key you
133
+ are trying to access is not there, so an example usage is the following:
134
+
135
+ void *data = raxFind(rax,mykey,mykey_len);
136
+ if (data == raxNotFound) return;
137
+ printf("Key value is %p\n", data);
138
+
139
+ raxFind() is a read only function so no out of memory conditions are
140
+ possible, the function never fails.
141
+
142
+ ## Deleting keys
143
+
144
+ Deleting the key is as you could imagine it, but with the ability to
145
+ return by reference the value associated to the key we are about to
146
+ delete:
147
+
148
+ int raxRemove(rax *rax, unsigned char *s, size_t len, void **old);
149
+
150
+ The function returns 1 if the key gets deleted, or 0 if the key was not
151
+ there. This function also does not fail for out of memory, however if
152
+ there is an out of memory condition while a key is being deleted, the
153
+ resulting tree nodes may not get re-compressed even if possible: the radix
154
+ tree may be less efficiently encoded in this case.
155
+
156
+ The `old` argument is optional, if passed will be set to the key associated
157
+ value if the function successfully finds and removes the key.
158
+
159
+ # Iterators
160
+
161
+ The Rax key space is ordered lexicographically, using the value of the
162
+ bytes the keys are composed of in order to decide which key is greater
163
+ between two keys. If the prefix is the same, the longer key is considered
164
+ to be greater.
165
+
166
+ Rax iterators allow to seek a given element based on different operators
167
+ and then to navigate the key space calling `raxNext()` and `raxPrev()`.
168
+
169
+ ## Basic iterator usage
170
+
171
+ Iterators are normally declared as local variables allocated on the stack,
172
+ and then initialized with the `raxStart` function:
173
+
174
+ raxIterator iter;
175
+ raxStart(&iter, rt); // Note that 'rt' is the radix tree pointer.
176
+
177
+ The function `raxStart` never fails and returns no value.
178
+ Once an iterator is initialized, it can be sought (sought is the past tens
179
+ of 'seek', which is not 'seeked', in case you wonder) in order to start
180
+ the iteration from the specified position. For this goal, the function
181
+ `raxSeek` is used:
182
+
183
+ int raxSeek(raxIterator *it, unsigned char *ele, size_t len, const char *op);
184
+
185
+ For instance one may want to seek the first element greater or equal to the
186
+ key `"foo"`:
187
+
188
+ raxSeek(&iter,">=",(unsigned char*)"foo",3);
189
+
190
+ The function raxSeek() returns 1 on success, or 0 on failure. Possible failures are:
191
+
192
+ 1. An invalid operator was passed as last argument.
193
+ 2. An out of memory condition happened while seeking the iterator.
194
+
195
+ Once the iterator is sought, it is possible to iterate using the function
196
+ `raxNext` and `raxPrev` as in the following example:
197
+
198
+ while(raxNext(&iter)) {
199
+ printf("Key: %.*s\n", (int)iter.key_len, (char*)iter.key);
200
+ }
201
+
202
+ The function `raxNext` returns elements starting from the element sought
203
+ with `raxSeek`, till the final element of the tree. When there are no more
204
+ elements, 0 is returned, otherwise the function returns 1. However the function
205
+ may return 0 when an out of memory condition happens as well: while it attempts
206
+ to always use the stack, if the tree depth is large or the keys are big the
207
+ iterator starts to use heap allocated memory.
208
+
209
+ The function `raxPrev` works exactly in the same way, but will move towards
210
+ the first element of the radix tree instead of moving towards the last
211
+ element.
212
+
213
+ # Releasing iterators
214
+
215
+ An iterator can be used multiple times, and can be sought again and again
216
+ using `raxSeek` without any need to call `raxStart` again. However, when the
217
+ iterator is not going to be used again, its memory must be reclaimed
218
+ with the following call:
219
+
220
+ raxStop(&iter);
221
+
222
+ Note that even if you do not call `raxStop`, most of the times you'll not
223
+ detect any memory leak, but this is just a side effect of how the
224
+ Rax implementation works: most of the times it will try to use the stack
225
+ allocated data structures. However for deep trees or large keys, heap memory
226
+ will be allocated, and failing to call `raxStop` will result into a memory
227
+ leak.
228
+
229
+ ## Seek operators
230
+
231
+ The function `raxSeek` can seek different elements based on the operator.
232
+ For instance in the example above we used the following call:
233
+
234
+ raxSeek(&iter,">=",(unsigned char*)"foo",3);
235
+
236
+ In order to seek the first element `>=` to the string `"foo"`. However
237
+ other operators are available. The first set are pretty obvious:
238
+
239
+ * `==` seek the element exactly equal to the given one.
240
+ * `>` seek the element immediately greater than the given one.
241
+ * `>=` seek the element equal, or immediately greater than the given one.
242
+ * `<` seek the element immediately smaller than the given one.
243
+ * `<=` seek the element equal, or immediately smaller than the given one.
244
+ * `^` seek the smallest element of the radix tree.
245
+ * `$` seek the greatest element of the radix tree.
246
+
247
+ When the last two operators, `^` or `$` are used, the key and key length
248
+ argument passed are completely ignored since they are not relevant.
249
+
250
+ Note how certain times the seek will be impossible, for example when the
251
+ radix tree contains no elements or when we are asking for a seek that is
252
+ not possible, like in the following case:
253
+
254
+ raxSeek(&iter,">",(unsigned char*)"zzzzz",5);
255
+
256
+ We may not have any element greater than `"zzzzz"`. In this case, what
257
+ happens is that the first call to `raxNext` or `raxPrev` will simply return
258
+ zero, so no elements are iterated.
259
+
260
+ ## Iterator stop condition
261
+
262
+ Sometimes we want to iterate specific ranges, for example from AAA to BBB.
263
+ In order to do so, we could seek and get the next element. However we need
264
+ to stop once the returned key is greater than BBB. The Rax library offers
265
+ the `raxCompare` function in order to avoid you need to code the same string
266
+ comparison function again and again based on the exact iteration you are
267
+ doing:
268
+
269
+ raxIterator iter;
270
+ raxStart(&iter);
271
+ raxSeek(&iter,">=",(unsigned char*)"AAA",3); // Seek the first element
272
+ while(raxNext(&iter)) {
273
+ if (raxCompare(&iter,">",(unsigned char*)"BBB",3)) break;
274
+ printf("Current key: %.*s\n", (int)iter.key_len,(char*)iter.key);
275
+ }
276
+ raxStop(&iter);
277
+
278
+ The above code shows a complete range iterator just printing the keys
279
+ traversed by iterating.
280
+
281
+ The prototype of the `raxCompare` function is the following:
282
+
283
+ int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key_len);
284
+
285
+ The operators supported are `>`, `>=`, `<`, `<=`, `==`.
286
+ The function returns 1 if the current iterator key satisfies the operator
287
+ compared to the provided key, otherwise 0 is returned.
288
+
289
+ ## Checking for iterator EOF condition
290
+
291
+ Sometimes we want to know if the itereator is in EOF state before calling
292
+ raxNext() or raxPrev(). The iterator EOF condition happens when there are
293
+ no more elements to return via raxNext() or raxPrev() call, because either
294
+ raxSeek() failed to seek the requested element, or because EOF was reached
295
+ while navigating the tree with raxPrev() and raxNext() calls.
296
+
297
+ This condition can be tested with the following function that returns 1
298
+ if EOF was reached:
299
+
300
+ int raxEOF(raxIterator *it);
301
+
302
+ ## Modifying the radix tree while iterating
303
+
304
+ In order to be efficient, the Rax iterator caches the exact node we are at,
305
+ so that at the next iteration step, it can start from where it left.
306
+ However an iterator has sufficient state in order to re-seek again
307
+ in case the cached node pointers are no longer valid. This problem happens
308
+ when we want to modify a radix tree during an iteration. A common pattern
309
+ is, for instance, deleting all the elements that match a given condition.
310
+
311
+ Fortunately there is a very simple way to do this, and the efficiency cost
312
+ is only paid as needed, that is, only when the tree is actually modified.
313
+ The solution consists of seeking the iterator again, with the current key,
314
+ once the tree is modified, like in the following example:
315
+
316
+ while(raxNext(&iter,...)) {
317
+ if (raxRemove(rax,...)) {
318
+ raxSeek(&iter,">",iter.key,iter.key_size);
319
+ }
320
+ }
321
+
322
+ In the above case we are iterating with `raxNext`, so we are going towards
323
+ lexicographically greater elements. Every time we remove an element, what we
324
+ need to do is to seek it again using the current element and the `>` seek
325
+ operator: this way we'll move to the next element with a new state representing
326
+ the current radix tree (after the change).
327
+
328
+ The same idea can be used in different contexts, considering the following:
329
+
330
+ * Iterators need to be sought again with `raxSeek` every time keys are added or removed while iterating.
331
+ * The current iterator key is always valid to access via `iter.key_size` and `iter.key`, even after it was deleted from the radix tree.
332
+
333
+ ## Re-seeking iterators after EOF
334
+
335
+ After iteration reaches an EOF condition since there are no more elements
336
+ to return, because we reached one or the other end of the radix tree, the
337
+ EOF condition is permanent, and even iterating in the reverse direction will
338
+ not produce any result.
339
+
340
+ The simplest way to continue the iteration, starting again from the last
341
+ element returned by the iterator, is simply to seek itself:
342
+
343
+ raxSeek(&iter,iter.key,iter.key_len,"==");
344
+
345
+ So for example in order to write a command that prints all the elements
346
+ of a radix tree from the first to the last, and later again from the last
347
+ to the first, reusing the same iterator, it is possible to use the following
348
+ approach:
349
+
350
+ raxSeek(&iter,"^",NULL,0);
351
+ while(raxNext(&iter,NULL,0,NULL))
352
+ printf("%.*s\n", (int)iter.key_len, (char*)iter.key);
353
+
354
+ raxSeek(&iter,"==",iter.key,iter.key_len);
355
+ while(raxPrev(&iter,NULL,0,NULL))
356
+ printf("%.*s\n", (int)iter.key_len, (char*)iter.key);
357
+
358
+ ## Random element selection
359
+
360
+ To extract a fair element from a radix tree so that every element is returned
361
+ with the same probability is not possible if we require that:
362
+
363
+ 1. The radix tree is not larger than expected (for example augmented with information that allows elements ranking).
364
+ 2. We want the operation to be fast, at worst logarithmic (so things like reservoir sampling are out since it's O(N)).
365
+
366
+ However a random walk which is long enough, in trees that are more or less balanced, produces acceptable results, is fast, and eventually returns every possible element, even if not with the right probability.
367
+
368
+ To perform a random walk, just seek an iterator anywhere and call the
369
+ following function:
370
+
371
+ int raxRandomWalk(raxIterator *it, size_t steps);
372
+
373
+ If the number of steps is set to 0, the function will perform a number of
374
+ random walk steps between 1 and two times the logarithm in base two of the
375
+ number of elements inside the tree, which is often enough to get a decent
376
+ result. Otherwise, you may specify the exact number of steps to take.
377
+
378
+ ## Printing trees
379
+
380
+ For debugging purposes, or educational ones, it is possible to use the
381
+ following call in order to get an ASCII art representation of a radix tree
382
+ and the nodes it is composed of:
383
+
384
+ raxShow(mytree);
385
+
386
+ However note that this works well enough for trees with a few elements, but
387
+ becomes hard to read for very large trees.
388
+
389
+ The following is an example of the output raxShow() produces after adding
390
+ the specified keys and values:
391
+
392
+ * alligator = (nil)
393
+ * alien = 0x1
394
+ * baloon = 0x2
395
+ * chromodynamic = 0x3
396
+ * romane = 0x4
397
+ * romanus = 0x5
398
+ * romulus = 0x6
399
+ * rubens = 0x7
400
+ * ruber = 0x8
401
+ * rubicon = 0x9
402
+ * rubicundus = 0xa
403
+ * all = 0xb
404
+ * rub = 0xc
405
+ * ba = 0xd
406
+
407
+ ```
408
+ [abcr]
409
+ `-(a) [l] -> [il]
410
+ `-(i) "en" -> []=0x1
411
+ `-(l) "igator"=0xb -> []=(nil)
412
+ `-(b) [a] -> "loon"=0xd -> []=0x2
413
+ `-(c) "hromodynamic" -> []=0x3
414
+ `-(r) [ou]
415
+ `-(o) [m] -> [au]
416
+ `-(a) [n] -> [eu]
417
+ `-(e) []=0x4
418
+ `-(u) [s] -> []=0x5
419
+ `-(u) "lus" -> []=0x6
420
+ `-(u) [b] -> [ei]=0xc
421
+ `-(e) [nr]
422
+ `-(n) [s] -> []=0x7
423
+ `-(r) []=0x8
424
+ `-(i) [c] -> [ou]
425
+ `-(o) [n] -> []=0x9
426
+ `-(u) "ndus" -> []=0xa
427
+ ```
428
+
429
+ # Running the Rax tests
430
+
431
+ To run the tests try:
432
+
433
+ $ make
434
+ $ ./rax-test
435
+
436
+ To run the benchmark:
437
+
438
+ $ make
439
+ $ ./rax-test --bench
440
+
441
+ To test Rax under OOM conditions:
442
+
443
+ $ make
444
+ $ ./rax-oom-test
445
+
446
+ The last one is very verbose currently.
447
+
448
+ In order to test with Valgrind, just run the tests using it, however
449
+ if you want accurate leaks detection, let Valgrind run the *whole* test,
450
+ since if you stop it earlier it will detect a lot of false positive memory
451
+ leaks. This is due to the fact that Rax put pointers at unaligned addresses
452
+ with `memcpy`, so it is not obvious where pointers are stored for Valgrind,
453
+ that will detect the leaks. However, at the end of the test, Valgrind will
454
+ detect that all the allocations were later freed, and will report that
455
+ there are no leaks.
456
+
457
+ # Debugging Rax
458
+
459
+ While investigating problems in Rax it is possible to turn debugging messages
460
+ on by compiling with the macro `RAX_DEBUG_MSG` enabled. Note that it's a lot
461
+ of output, and may make running large tests too slow.
462
+
463
+ In order to active debugging selectively in a dynamic way, it is possible to
464
+ use the function raxSetDebugMsg(0) or raxSetDebugMsg(1) to disable/enable
465
+ debugging.
466
+
467
+ A problem when debugging code doing complex memory operations like a radix
468
+ tree implemented the way Rax is implemented, is to understand where the bug
469
+ happens (for instance a memory corruption). For that goal it is possible to
470
+ use the function raxTouch() that will basically recursively access every
471
+ node in the radix tree, itearting every sub child. In combination with
472
+ tools like Valgrind, it is possible then to perform the following pattern
473
+ in order to narrow down the state causing a give bug:
474
+
475
+ 1. The rax-test is executed using Valgrind, adding a printf() so that for
476
+ the fuzz tester we see what iteration in the loop we are in.
477
+ 2. After every modification of the radix tree made by the fuzz tester
478
+ in rax-test.c, we add a call to raxTouch().
479
+ 3. Now as soon as an operation will corrupt the tree, raxTouch() will
480
+ detect it (via Valgrind) immediately. We can add more calls to narrow
481
+ the state.
482
+ 4. At this point a good idea is to enable Rax debugging messages immediately
483
+ before the moment the tree is corrupted, to see what happens. This can
484
+ be achieved by adding a few "if" statements inside the code, since we
485
+ know the iteration that causes the corruption (because of step 1).
486
+
487
+ This method was used with success during rafactorings in order to debug the
488
+ introduced bugs.
@@ -0,0 +1,88 @@
1
+ /*
2
+ * Copyright 2001-2010 Georges Menie (www.menie.org)
3
+ * Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style)
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of the University of California, Berkeley nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
19
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ /* CRC16 implementation according to CCITT standards.
31
+ *
32
+ * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the
33
+ * following parameters:
34
+ *
35
+ * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN"
36
+ * Width : 16 bit
37
+ * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1)
38
+ * Initialization : 0000
39
+ * Reflect Input byte : False
40
+ * Reflect Output CRC : False
41
+ * Xor constant to output CRC : 0000
42
+ * Output for "123456789" : 31C3
43
+ */
44
+
45
+ #include <stdint.h>
46
+
47
+ static const uint16_t crc16tab[256]= {
48
+ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
49
+ 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
50
+ 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
51
+ 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
52
+ 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
53
+ 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
54
+ 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
55
+ 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
56
+ 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
57
+ 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
58
+ 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
59
+ 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
60
+ 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
61
+ 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
62
+ 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
63
+ 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
64
+ 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
65
+ 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
66
+ 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
67
+ 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
68
+ 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
69
+ 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
70
+ 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
71
+ 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
72
+ 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
73
+ 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
74
+ 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
75
+ 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
76
+ 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
77
+ 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
78
+ 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
79
+ 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
80
+ };
81
+
82
+ uint16_t crc16(const char *buf, int len) {
83
+ int counter;
84
+ uint16_t crc = 0;
85
+ for (counter = 0; counter < len; counter++)
86
+ crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF];
87
+ return crc;
88
+ }