tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

crc32c_test.cc (7502B)


      1 // Copyright 2022 The Abseil Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/crc/crc32c.h"
     16 
     17 #include <algorithm>
     18 #include <cstddef>
     19 #include <cstdint>
     20 #include <cstring>
     21 #include <sstream>
     22 #include <string>
     23 
     24 #include "gtest/gtest.h"
     25 #include "absl/crc/internal/crc32c.h"
     26 #include "absl/strings/str_cat.h"
     27 #include "absl/strings/str_format.h"
     28 #include "absl/strings/string_view.h"
     29 
     30 namespace {
     31 
     32 TEST(CRC32C, RFC3720) {
     33  // Test the results of the vectors from
     34  // https://www.rfc-editor.org/rfc/rfc3720#appendix-B.4
     35  char data[32];
     36 
     37  // 32 bytes of ones.
     38  memset(data, 0, sizeof(data));
     39  EXPECT_EQ(absl::ComputeCrc32c(absl::string_view(data, sizeof(data))),
     40            absl::crc32c_t{0x8a9136aa});
     41 
     42  // 32 bytes of ones.
     43  memset(data, 0xff, sizeof(data));
     44  EXPECT_EQ(absl::ComputeCrc32c(absl::string_view(data, sizeof(data))),
     45            absl::crc32c_t{0x62a8ab43});
     46 
     47  // 32 incrementing bytes.
     48  for (int i = 0; i < 32; ++i) data[i] = static_cast<char>(i);
     49  EXPECT_EQ(absl::ComputeCrc32c(absl::string_view(data, sizeof(data))),
     50            absl::crc32c_t{0x46dd794e});
     51 
     52  // 32 decrementing bytes.
     53  for (int i = 0; i < 32; ++i) data[i] = static_cast<char>(31 - i);
     54  EXPECT_EQ(absl::ComputeCrc32c(absl::string_view(data, sizeof(data))),
     55            absl::crc32c_t{0x113fdb5c});
     56 
     57  // An iSCSI - SCSI Read (10) Command PDU.
     58  constexpr uint8_t cmd[48] = {
     59      0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     60      0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
     61      0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x28, 0x00, 0x00, 0x00,
     62      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     63  };
     64  EXPECT_EQ(absl::ComputeCrc32c(absl::string_view(
     65                reinterpret_cast<const char*>(cmd), sizeof(cmd))),
     66            absl::crc32c_t{0xd9963a56});
     67 }
     68 
     69 std::string TestString(size_t len) {
     70  std::string result;
     71  result.reserve(len);
     72  for (size_t i = 0; i < len; ++i) {
     73    result.push_back(static_cast<char>(i % 256));
     74  }
     75  return result;
     76 }
     77 
     78 TEST(CRC32C, Compute) {
     79  EXPECT_EQ(absl::ComputeCrc32c(""), absl::crc32c_t{0});
     80  EXPECT_EQ(absl::ComputeCrc32c("hello world"), absl::crc32c_t{0xc99465aa});
     81 }
     82 
     83 TEST(CRC32C, Extend) {
     84  uint32_t base = 0xC99465AA;  // CRC32C of "Hello World"
     85  std::string extension = "Extension String";
     86 
     87  EXPECT_EQ(
     88      absl::ExtendCrc32c(absl::crc32c_t{base}, extension),
     89      absl::crc32c_t{0xD2F65090});  // CRC32C of "Hello WorldExtension String"
     90 }
     91 
     92 TEST(CRC32C, ExtendByZeroes) {
     93  std::string base = "hello world";
     94  absl::crc32c_t base_crc = absl::crc32c_t{0xc99465aa};
     95 
     96  constexpr size_t kExtendByValues[] = {100, 10000, 100000};
     97  for (const size_t extend_by : kExtendByValues) {
     98    SCOPED_TRACE(extend_by);
     99    absl::crc32c_t crc2 = absl::ExtendCrc32cByZeroes(base_crc, extend_by);
    100    EXPECT_EQ(crc2, absl::ComputeCrc32c(base + std::string(extend_by, '\0')));
    101  }
    102 }
    103 
    104 TEST(CRC32C, UnextendByZeroes) {
    105  constexpr size_t kExtendByValues[] = {2, 200, 20000, 200000, 20000000};
    106  constexpr size_t kUnextendByValues[] = {0, 100, 10000, 100000, 10000000};
    107 
    108  for (auto seed_crc : {absl::crc32c_t{0}, absl::crc32c_t{0xc99465aa}}) {
    109    SCOPED_TRACE(seed_crc);
    110    for (const size_t size_1 : kExtendByValues) {
    111      for (const size_t size_2 : kUnextendByValues) {
    112        size_t extend_size = std::max(size_1, size_2);
    113        size_t unextend_size = std::min(size_1, size_2);
    114        SCOPED_TRACE(extend_size);
    115        SCOPED_TRACE(unextend_size);
    116 
    117        // Extending by A zeroes an unextending by B<A zeros should be identical
    118        // to extending by A-B zeroes.
    119        absl::crc32c_t crc1 = seed_crc;
    120        crc1 = absl::ExtendCrc32cByZeroes(crc1, extend_size);
    121        crc1 = absl::crc_internal::UnextendCrc32cByZeroes(crc1, unextend_size);
    122 
    123        absl::crc32c_t crc2 = seed_crc;
    124        crc2 = absl::ExtendCrc32cByZeroes(crc2, extend_size - unextend_size);
    125 
    126        EXPECT_EQ(crc1, crc2);
    127      }
    128    }
    129  }
    130 
    131  constexpr size_t kSizes[] = {0, 1, 100, 10000};
    132  for (const size_t size : kSizes) {
    133    SCOPED_TRACE(size);
    134    std::string string_before = TestString(size);
    135    std::string string_after = string_before + std::string(size, '\0');
    136 
    137    absl::crc32c_t crc_before = absl::ComputeCrc32c(string_before);
    138    absl::crc32c_t crc_after = absl::ComputeCrc32c(string_after);
    139 
    140    EXPECT_EQ(crc_before,
    141              absl::crc_internal::UnextendCrc32cByZeroes(crc_after, size));
    142  }
    143 }
    144 
    145 TEST(CRC32C, Concat) {
    146  std::string hello = "Hello, ";
    147  std::string world = "world!";
    148  std::string hello_world = absl::StrCat(hello, world);
    149 
    150  absl::crc32c_t crc_a = absl::ComputeCrc32c(hello);
    151  absl::crc32c_t crc_b = absl::ComputeCrc32c(world);
    152  absl::crc32c_t crc_ab = absl::ComputeCrc32c(hello_world);
    153 
    154  EXPECT_EQ(absl::ConcatCrc32c(crc_a, crc_b, world.size()), crc_ab);
    155 }
    156 
    157 TEST(CRC32C, Memcpy) {
    158  constexpr size_t kBytesSize[] = {0, 1, 20, 500, 100000};
    159  for (size_t bytes : kBytesSize) {
    160    SCOPED_TRACE(bytes);
    161    std::string sample_string = TestString(bytes);
    162    std::string target_buffer = std::string(bytes, '\0');
    163 
    164    absl::crc32c_t memcpy_crc =
    165        absl::MemcpyCrc32c(&(target_buffer[0]), sample_string.data(), bytes);
    166    absl::crc32c_t compute_crc = absl::ComputeCrc32c(sample_string);
    167 
    168    EXPECT_EQ(memcpy_crc, compute_crc);
    169    EXPECT_EQ(sample_string, target_buffer);
    170  }
    171 }
    172 
    173 TEST(CRC32C, RemovePrefix) {
    174  std::string hello = "Hello, ";
    175  std::string world = "world!";
    176  std::string hello_world = absl::StrCat(hello, world);
    177 
    178  absl::crc32c_t crc_a = absl::ComputeCrc32c(hello);
    179  absl::crc32c_t crc_b = absl::ComputeCrc32c(world);
    180  absl::crc32c_t crc_ab = absl::ComputeCrc32c(hello_world);
    181 
    182  EXPECT_EQ(absl::RemoveCrc32cPrefix(crc_a, crc_ab, world.size()), crc_b);
    183 }
    184 
    185 TEST(CRC32C, RemoveSuffix) {
    186  std::string hello = "Hello, ";
    187  std::string world = "world!";
    188  std::string hello_world = absl::StrCat(hello, world);
    189 
    190  absl::crc32c_t crc_a = absl::ComputeCrc32c(hello);
    191  absl::crc32c_t crc_b = absl::ComputeCrc32c(world);
    192  absl::crc32c_t crc_ab = absl::ComputeCrc32c(hello_world);
    193 
    194  EXPECT_EQ(absl::RemoveCrc32cSuffix(crc_ab, crc_b, world.size()), crc_a);
    195 }
    196 
    197 TEST(CRC32C, InsertionOperator) {
    198  {
    199    std::ostringstream buf;
    200    buf << absl::crc32c_t{0xc99465aa};
    201    EXPECT_EQ(buf.str(), "c99465aa");
    202  }
    203  {
    204    std::ostringstream buf;
    205    buf << absl::crc32c_t{0};
    206    EXPECT_EQ(buf.str(), "00000000");
    207  }
    208  {
    209    std::ostringstream buf;
    210    buf << absl::crc32c_t{17};
    211    EXPECT_EQ(buf.str(), "00000011");
    212  }
    213 }
    214 
    215 TEST(CRC32C, AbslStringify) {
    216  // StrFormat
    217  EXPECT_EQ(absl::StrFormat("%v", absl::crc32c_t{0xc99465aa}), "c99465aa");
    218  EXPECT_EQ(absl::StrFormat("%v", absl::crc32c_t{0}), "00000000");
    219  EXPECT_EQ(absl::StrFormat("%v", absl::crc32c_t{17}), "00000011");
    220 
    221  // StrCat
    222  EXPECT_EQ(absl::StrCat(absl::crc32c_t{0xc99465aa}), "c99465aa");
    223  EXPECT_EQ(absl::StrCat(absl::crc32c_t{0}), "00000000");
    224  EXPECT_EQ(absl::StrCat(absl::crc32c_t{17}), "00000011");
    225 }
    226 
    227 }  // namespace