1 /**
2  * Copyright (C) Mellanox Technologies Ltd. 2001-2016.  ALL RIGHTS RESERVED.
3  *
4  * See file LICENSE for terms.
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #  include "config.h"
9 #endif
10 
11 #include <ucs/algorithm/crc.h>
12 
13 #include <string.h>
14 
15 
16 /* CRC-16-CCITT */
17 #define UCS_CRC16_POLY    0x8408u
18 
19 /* CRC-32 (ISO 3309) */
20 #define UCS_CRC32_POLY    0xedb88320l
21 
22 #define UCS_CRC_CALC(_width, _buffer, _size, _crc) \
23     do { \
24         const uint8_t *end = (const uint8_t*)(UCS_PTR_BYTE_OFFSET(_buffer, _size)); \
25         const uint8_t *p; \
26         uint8_t bit; \
27         \
28         if ((_size) != 0) { \
29             for (p = (_buffer); p < end; ++p) { \
30                 (_crc) ^= *p; \
31                 for (bit = 0; bit < 8; ++bit) { \
32                     (_crc) = ((_crc) >> 1) ^ (-(int)((_crc) & 1) & \
33                                               UCS_CRC ## _width ## _POLY); \
34                 } \
35             } \
36         } \
37         (_crc) = ~(_crc); \
38     } while (0)
39 
40 
ucs_crc16(const void * buffer,size_t size)41 uint16_t ucs_crc16(const void *buffer, size_t size)
42 {
43     uint16_t crc = UINT16_MAX;
44     UCS_CRC_CALC(16, buffer, size, crc);
45     return crc;
46 }
47 
ucs_crc16_string(const char * s)48 uint16_t ucs_crc16_string(const char *s)
49 {
50     return ucs_crc16((const char*)s, strlen(s));
51 }
52 
ucs_crc32(uint32_t prev_crc,const void * buffer,size_t size)53 uint32_t ucs_crc32(uint32_t prev_crc, const void *buffer, size_t size)
54 {
55     uint32_t crc = ~prev_crc;
56     UCS_CRC_CALC(32, buffer, size, crc);
57     return crc;
58 }
59