0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Checksum.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Hypertable. If not, see <http://www.gnu.org/licenses/>
18  */
19 
25 #include "Compat.h"
26 #include <arpa/inet.h>
27 #include <zlib.h>
28 #include "Checksum.h"
29 
30 namespace Hypertable {
31 
32 #define HT_F32_DO1(buf,i) \
33  sum1 += ((uint16_t)buf[i] << 8) | buf[i + 1]; sum2 += sum1
34 #define HT_F32_DO2(buf, i) HT_F32_DO1(buf, i); HT_F32_DO1(buf, i + 2);
35 #define HT_F32_DO4(buf, i) HT_F32_DO2(buf, i); HT_F32_DO2(buf, i + 4);
36 #define HT_F32_DO8(buf, i) HT_F32_DO4(buf, i); HT_F32_DO4(buf, i + 8);
37 #define HT_F32_DO16(buf, i) HT_F32_DO8(buf, i); HT_F32_DO8(buf, i + 16);
38 
39 /* cf. http://en.wikipedia.org/wiki/Fletcher%27s_checksum
40  */
41 uint32_t
42 fletcher32(const void *data8, size_t len8) {
43  /* data may not be aligned properly and would segfault on
44  * many systems if cast and used as 16-bit words
45  */
46  const uint8_t *data = (const uint8_t *)data8;
47  uint32_t sum1 = 0xffff, sum2 = 0xffff;
48  size_t len = len8 / 2; /* loop works on 16-bit words */
49 
50  while (len) {
51  /* 360 is the largest number of sums that can be
52  * performed without integer overflow
53  */
54  unsigned tlen = len > 360 ? 360 : len;
55  len -= tlen;
56 
57  if (tlen >= 16) do {
58  HT_F32_DO16(data, 0);
59  data += 32;
60  tlen -= 16;
61  } while (tlen >= 16);
62 
63  if (tlen != 0) do {
64  HT_F32_DO1(data, 0);
65  data += 2;
66  } while (--tlen);
67 
68  sum1 = (sum1 & 0xffff) + (sum1 >> 16);
69  sum2 = (sum2 & 0xffff) + (sum2 >> 16);
70  }
71 
72  /* Check for odd number of bytes */
73  if (len8 & 1) {
74  sum1 += ((uint16_t)*data) << 8;
75  sum2 += sum1;
76  sum1 = (sum1 & 0xffff) + (sum1 >> 16);
77  sum2 = (sum2 & 0xffff) + (sum2 >> 16);
78  }
79 
80  /* Second reduction step to reduce sums to 16 bits */
81  sum1 = (sum1 & 0xffff) + (sum1 >> 16);
82  sum2 = (sum2 & 0xffff) + (sum2 >> 16);
83  return (sum2 << 16) | sum1;
84 }
85 
86 } // namespace Hypertable
87 
88 /* vim: et sw=2
89  */
#define HT_F32_DO1(buf, i)
Definition: Checksum.cc:32
#define HT_F32_DO16(buf, i)
Definition: Checksum.cc:37
uint32_t fletcher32(const void *data8, size_t len8)
Compute fletcher32 checksum for arbitary data.
Definition: Checksum.cc:42
Compatibility Macros for C/C++.
Hypertable definitions
Implementation of checksum routines.