1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
// Copyright 2010 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "std_headers.h"
#include "interface.h"
static const size_t kRollWindow = 4;
static const unsigned char kTestData[] = "abcdefgh";
static const int kTestDataHead =
static_cast<size_t>((sizeof(kTestData) - 1) / 4);
static const int kTestDataTail =
static_cast<size_t>(sizeof(kTestData) - 1 - kTestDataHead);
typedef crcutil_interface::UINT64 uint64;
// GCC -- up to 4.5.0 inclusively -- is not aware that the right format
// to print "long long" is "%ll[oudx]". Such nonsense does not prevent
// it from complaining about format mismatch, though. Here is the cure.
void xprintf(const char *format, ...) {
va_list va;
va_start(va, format);
vprintf(format, va);
va_end(va);
fflush(stdout);
}
//
// Please notice that when working with 64-bit and smaller CRCs,
// the use of "hi" part of CRC value is unnecessary.
//
void Show(const crcutil_interface::CRC *crc) {
char buffer[sizeof(kTestData) + 32];
//
// Access CRC properties.
//
uint64 lo;
crc->GeneratingPolynomial(&lo);
xprintf("Generating polynomial 0x%llx, degree %llu",
lo,
static_cast<uint64>(crc->Degree()));
crc->CanonizeValue(&lo);
xprintf(", canonize_value=0x%llx", lo);
crc->RollStartValue(&lo);
xprintf(", roll start value=0x%llx, roll window=%llu",
lo,
static_cast<uint64>(crc->RollWindowBytes()));
//
// Check integrity of CRC tables.
//
crc->SelfCheckValue(&lo);
xprintf(", self check value 0x%llx\n", lo);
//
// Compute CRC.
//
lo = 0;
crc->Compute(kTestData, sizeof(kTestData) - 1, &lo);
xprintf("CRC32C(\"%s\") = 0x%llx\n", kTestData, lo);
//
// Compute CRC (incrementally).
//
lo = 0;
crc->Compute(kTestData, kTestDataHead, &lo);
xprintf("CRC32C(\"%.*s\", 0) = 0x%llx, ", kTestDataHead, kTestData, lo);
crc->Compute(kTestData + kTestDataHead, kTestDataTail, &lo);
xprintf("CRC32C(\"%s\", CRC32(\"%.*s\", 0)) = 0x%llx = CRC32(\"%s\")\n",
kTestData + kTestDataHead, kTestDataHead, kTestData, lo, kTestData);
//
// Compute CRC of a message filled with 0s.
//
lo = 1;
crc->CrcOfZeroes(sizeof(buffer), &lo);
uint64 lo1 = 1;
memset(buffer, 0, sizeof(buffer));
crc->Compute(buffer, sizeof(buffer), &lo1);
xprintf("CRC of %d zeroes = %llx, expected %llx\n",
static_cast<int>(sizeof(buffer)),
lo,
lo1);
//
// Use rolling CRC.
//
xprintf("RollingCrc expected =");
for (size_t i = 0; i <= kRollWindow; ++i) {
crc->RollStartValue(&lo);
crc->Compute(kTestData + i, kRollWindow, &lo);
xprintf(" 0x%llx", lo);
}
xprintf("\n");
crc->RollStart(kTestData, &lo, NULL);
xprintf("RollingCrc actual = 0x%llx", lo);
for (size_t i = 1; i <= kRollWindow; ++i) {
crc->Roll(kTestData[i - 1], kTestData[i - 1 + kRollWindow], &lo, NULL);
xprintf(" 0x%llx", lo);
}
xprintf("\n");
//
// Change initial value.
//
lo = 0;
crc->Compute(kTestData, sizeof(kTestData) - 1, &lo);
uint64 lo1_expected = 1;
crc->Compute(kTestData, sizeof(kTestData) - 1, &lo1_expected);
lo1 = lo;
crc->ChangeStartValue(0, 0, // old start value
1, 0, // new start value
sizeof(kTestData) - 1,
&lo1);
xprintf("CRC(\"%s\", 0) = 0x%llx, CRC(\"%s\", 1)=0x%llx, expected 0x%llx\n",
kTestData, lo, kTestData, lo1, lo1_expected);
//
// Concatenate CRCs.
//
uint64 start_value = 1;
lo = start_value;
crc->Compute(kTestData, kTestDataHead, &lo);
lo1 = 0;
crc->Compute(kTestData + kTestDataHead, kTestDataTail, &lo1);
uint64 lo2 = lo;
crc->Concatenate(lo1, 0, kTestDataTail, &lo2);
uint64 lo2_expected = start_value;
crc->Compute(kTestData, sizeof(kTestData) - 1, &lo2_expected);
xprintf("CRC(\"%.*s\", 1) = 0x%llx, CRC(\"%s\", 0)=0x%llx, "
"CRC(\"%s\", 1) = 0x%llx, expected 0x%llx\n",
kTestDataHead, kTestData, lo,
kTestData + kTestDataHead, lo1,
kTestData, lo2,
lo2_expected);
//
// Store complementary CRC so that CRC of a message followed
// by complementary CRC value produces predefined result (e.g. 0).
//
memcpy(buffer, kTestData, sizeof(kTestData) - 1);
lo = 1;
crc->Compute(buffer, sizeof(kTestData) - 1, &lo);
size_t stored_crc_bytes = crc->StoreComplementaryCrc(
buffer + sizeof(kTestData) - 1,
lo, 0,
0);
// Compute CRC of message + complementary CRC using the same start value
// (start value could be changed via ChangeStartValue()).
lo1 = 1;
crc->Compute(buffer, sizeof(kTestData) - 1 + stored_crc_bytes, &lo1);
xprintf("Crc of message + complementary CRC = %llx, expected 0\n", lo1);
//
// Store CRC after the message and ensure that CRC of message + its
// CRC produces constant result irrespective of message data.
//
memcpy(buffer, kTestData, sizeof(kTestData) - 1);
lo = 1;
crc->Compute(buffer, sizeof(kTestData) - 1, &lo);
stored_crc_bytes = crc->StoreCrc(buffer + sizeof(kTestData) - 1, lo);
// Compute CRC of message + its CRC using start value of 0.
lo1 = 1;
crc->Compute(buffer, sizeof(kTestData) - 1 + stored_crc_bytes, &lo1);
// Ensure that it matches "predicted" constant value, irrespective
// of a message or CRC start value.
crc->CrcOfCrc(&lo2);
xprintf("CrcOfCrc=%llx, expected %llx\n", lo1, lo2);
xprintf("\n");
}
void ShowAndDelete(crcutil_interface::CRC *crc) {
Show(crc);
crc->Delete();
}
int main() {
ShowAndDelete(crcutil_interface::CRC::Create(
0xEB31D82E, 0, 32, true, 0x1111, 0, kRollWindow,
crcutil_interface::CRC::IsSSE42Available(), NULL));
ShowAndDelete(crcutil_interface::CRC::Create(
0x82f63b78, 0, 32, true, 0x2222, 0, kRollWindow,
crcutil_interface::CRC::IsSSE42Available(), NULL));
return 0;
}
|