xref: /aosp_15_r20/external/pigweed/pw_checksum/crc32_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // 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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_checksum/crc32.h"
15 
16 #include <string_view>
17 
18 #include "public/pw_checksum/crc32.h"
19 #include "pw_bytes/array.h"
20 #include "pw_span/span.h"
21 #include "pw_unit_test/framework.h"
22 
23 namespace pw::checksum {
24 namespace {
25 
26 // The expected CRC32 values were calculated using
27 //
28 //   http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
29 //
30 // with polynomial 0x4C11DB7, initial value 0xFFFFFFFF.
31 
32 constexpr auto kBytes = bytes::Array<1, 2, 3, 4, 5, 6, 7, 8, 9>();
33 constexpr auto kBytesPart0 = bytes::Array<1, 2, 3, 4, 5>();
34 constexpr auto kBytesPart1 = bytes::Array<6, 7, 8, 9>();
35 constexpr uint32_t kBufferCrc = 0x40EFAB9E;
36 
37 constexpr std::string_view kString =
38     "In the beginning the Universe was created. This has made a lot of "
39     "people very angry and been widely regarded as a bad move.";
40 constexpr uint32_t kStringCrc = 0x9EC87F88;
41 
TEST(Crc32,Empty)42 TEST(Crc32, Empty) {
43   EXPECT_EQ(Crc32::Calculate(span<std::byte>()), PW_CHECKSUM_EMPTY_CRC32);
44   EXPECT_EQ(Crc32EightBit::Calculate(span<std::byte>()),
45             PW_CHECKSUM_EMPTY_CRC32);
46   EXPECT_EQ(Crc32FourBit::Calculate(span<std::byte>()),
47             PW_CHECKSUM_EMPTY_CRC32);
48   EXPECT_EQ(Crc32OneBit::Calculate(span<std::byte>()), PW_CHECKSUM_EMPTY_CRC32);
49 }
50 
TEST(Crc32,Buffer)51 TEST(Crc32, Buffer) {
52   EXPECT_EQ(Crc32::Calculate(as_bytes(span(kBytes))), kBufferCrc);
53   EXPECT_EQ(Crc32EightBit::Calculate(as_bytes(span(kBytes))), kBufferCrc);
54   EXPECT_EQ(Crc32FourBit::Calculate(as_bytes(span(kBytes))), kBufferCrc);
55   EXPECT_EQ(Crc32OneBit::Calculate(as_bytes(span(kBytes))), kBufferCrc);
56 }
57 
TEST(Crc32,String)58 TEST(Crc32, String) {
59   EXPECT_EQ(Crc32::Calculate(as_bytes(span(kString))), kStringCrc);
60   EXPECT_EQ(Crc32EightBit::Calculate(as_bytes(span(kString))), kStringCrc);
61   EXPECT_EQ(Crc32FourBit::Calculate(as_bytes(span(kString))), kStringCrc);
62   EXPECT_EQ(Crc32OneBit::Calculate(as_bytes(span(kString))), kStringCrc);
63 }
64 
65 template <typename CrcVariant>
TestByByte()66 void TestByByte() {
67   CrcVariant crc;
68   for (std::byte b : kBytes) {
69     crc.Update(b);
70   }
71   EXPECT_EQ(crc.value(), kBufferCrc);
72 }
73 
TEST(Crc32Class,ByteByByte)74 TEST(Crc32Class, ByteByByte) {
75   TestByByte<Crc32>();
76   TestByByte<Crc32EightBit>();
77   TestByByte<Crc32FourBit>();
78   TestByByte<Crc32OneBit>();
79 }
80 
81 template <typename CrcVariant>
TestBuffer()82 void TestBuffer() {
83   CrcVariant crc32;
84   crc32.Update(as_bytes(span(kBytes)));
85   EXPECT_EQ(crc32.value(), kBufferCrc);
86 }
87 
TEST(Crc32Class,Buffer)88 TEST(Crc32Class, Buffer) {
89   TestBuffer<Crc32>();
90   TestBuffer<Crc32EightBit>();
91   TestBuffer<Crc32FourBit>();
92   TestBuffer<Crc32OneBit>();
93 }
94 
95 template <typename CrcVariant>
TestBufferAppend()96 void TestBufferAppend() {
97   CrcVariant crc32;
98   crc32.Update(kBytesPart0);
99   crc32.Update(kBytesPart1);
100   EXPECT_EQ(crc32.value(), kBufferCrc);
101 }
102 
TEST(Crc32Class,BufferAppend)103 TEST(Crc32Class, BufferAppend) {
104   TestBufferAppend<Crc32>();
105   TestBufferAppend<Crc32EightBit>();
106   TestBufferAppend<Crc32FourBit>();
107   TestBufferAppend<Crc32OneBit>();
108 }
109 
110 template <typename CrcVariant>
TestString()111 void TestString() {
112   CrcVariant crc32;
113   crc32.Update(as_bytes(span(kString)));
114   EXPECT_EQ(crc32.value(), kStringCrc);
115 }
116 
TEST(Crc32Class,String)117 TEST(Crc32Class, String) {
118   TestString<Crc32>();
119   TestString<Crc32EightBit>();
120   TestString<Crc32FourBit>();
121   TestString<Crc32OneBit>();
122 }
123 
124 extern "C" uint32_t CallChecksumCrc32(const void* data, size_t size_bytes);
125 extern "C" uint32_t CallChecksumCrc32Append(const void* data,
126                                             size_t size_bytes,
127                                             uint32_t value);
128 
TEST(Crc32FromC,Buffer)129 TEST(Crc32FromC, Buffer) {
130   EXPECT_EQ(CallChecksumCrc32(kBytes.data(), kBytes.size()), kBufferCrc);
131 }
132 
TEST(Crc32FromC,String)133 TEST(Crc32FromC, String) {
134   EXPECT_EQ(CallChecksumCrc32(kString.data(), kString.size()), kStringCrc);
135 }
136 
TEST(Crc32AppendFromC,Buffer)137 TEST(Crc32AppendFromC, Buffer) {
138   uint32_t crc = PW_CHECKSUM_EMPTY_CRC32;
139   for (std::byte b : kBytes) {
140     crc = CallChecksumCrc32Append(&b, 1, crc);
141   }
142 
143   EXPECT_EQ(crc, kBufferCrc);
144 }
145 
TEST(Crc32AppendFromC,String)146 TEST(Crc32AppendFromC, String) {
147   EXPECT_EQ(CallChecksumCrc32Append(
148                 kString.data(), kString.size(), PW_CHECKSUM_EMPTY_CRC32),
149             kStringCrc);
150 }
151 
152 }  // namespace
153 }  // namespace pw::checksum
154