v2 / vlib / hash / crc32 / crc32_test.v
157 lines · 133 sloc · 4.06 KB · ef11575ce2f92fe4353ad9fce591499ad0889859
Raw
1import hash.crc32
2
3const reflected_test_polys = [crc32.ieee, crc32.crc32c, crc32.crc32k, crc32.crc32q_reflected]
4
5fn sum_for_reflected_poly(poly u32, data []u8) u32 {
6 return match poly {
7 crc32.ieee { crc32.sum(data) }
8 crc32.crc32c { crc32.sum_crc32c(data) }
9 crc32.crc32k { crc32.sum_crc32k(data) }
10 crc32.crc32q_reflected { crc32.sum_with_poly(crc32.crc32q_reflected, data) }
11 else { panic('unexpected polynomial in test') }
12 }
13}
14
15fn expected_reflected_crc_123456789(poly u32) u32 {
16 return match poly {
17 crc32.ieee { u32(0xcbf43926) }
18 crc32.crc32c { u32(0xe3069283) }
19 crc32.crc32k { u32(0x2d3dd0ae) }
20 crc32.crc32q_reflected { u32(0xa9cc8179) }
21 else { panic('unexpected polynomial in test') }
22 }
23}
24
25fn expected_reflected_crc_a(poly u32) u32 {
26 return match poly {
27 crc32.ieee { u32(0xe8b7be43) }
28 crc32.crc32c { u32(0xc1d04330) }
29 crc32.crc32k { u32(0x0da2aa8a) }
30 crc32.crc32q_reflected { u32(0x248ca0a3) }
31 else { panic('unexpected polynomial in test') }
32 }
33}
34
35fn assert_reflected_poly_paths_match(poly u32, data []u8) {
36 c := crc32.new(poly)
37 by_new := c.checksum(data)
38 assert by_new == crc32.sum_with_poly(poly, data)
39 assert by_new == sum_for_reflected_poly(poly, data)
40}
41
42fn test_hash_crc32() {
43 b1 := 'testing crc32'.bytes()
44 sum1 := crc32.sum(b1)
45 assert sum1 == u32(1212124400)
46 assert sum1.hex() == '483f8cf0'
47
48 c := crc32.new(crc32.ieee)
49 b2 := 'testing crc32 again'.bytes()
50 sum2 := c.checksum(b2)
51 assert sum2 == u32(1420327025)
52 assert sum2.hex() == '54a87871'
53}
54
55fn test_hash_crc32_variants() {
56 data := '123456789'.bytes()
57 for poly in reflected_test_polys {
58 expected := expected_reflected_crc_123456789(poly)
59 assert sum_for_reflected_poly(poly, data) == expected
60 assert_reflected_poly_paths_match(poly, data)
61 }
62}
63
64fn test_hash_crc32q_standard() {
65 data := '123456789'.bytes()
66 assert crc32.sum_crc32q(data) == u32(0x3010bf7f)
67 assert crc32.sum_with_poly(crc32.crc32q, data) == u32(0x3010bf7f)
68 assert crc32.sum_crc32q('a'.bytes()) == u32(0xd1112b6b)
69}
70
71fn test_hash_crc32_update() {
72 data := '123456789'.bytes()
73 part1 := data[..4]
74 part2 := data[4..]
75
76 c := crc32.new(crc32.ieee)
77 mut acc := u32(0)
78 acc = c.update(acc, part1)
79 acc = c.update(acc, part2)
80
81 assert acc == c.checksum(data)
82 assert acc.hex() == 'cbf43926'
83}
84
85fn test_hash_crc32_edge_cases() {
86 empty := ''.bytes()
87 one := 'a'.bytes()
88 for poly in reflected_test_polys {
89 assert sum_for_reflected_poly(poly, empty) == u32(0)
90 assert sum_for_reflected_poly(poly, one) == expected_reflected_crc_a(poly)
91 }
92 assert crc32.sum_crc32q(empty) == u32(0)
93}
94
95fn test_hash_crc32_sum_with_poly() {
96 data := 'variant helper'.bytes()
97 for poly in reflected_test_polys {
98 assert_reflected_poly_paths_match(poly, data)
99 }
100 assert crc32.sum_with_poly(crc32.crc32q, data) == crc32.sum_crc32q(data)
101}
102
103fn test_hash_crc32_sum_with_poly_custom() {
104 data := 'custom poly checksum'.bytes()
105 poly := u32(0xa833982b)
106
107 assert crc32.sum_with_poly(poly, data) == crc32.new(poly).checksum(data)
108}
109
110fn test_hash_crc32_all_polys_consistent() {
111 data := 'all polys consistent'.bytes()
112 part1 := data[..7]
113 part2 := data[7..]
114
115 for poly in reflected_test_polys {
116 c := crc32.new(poly)
117 full := c.checksum(data)
118
119 mut split := u32(0)
120 split = c.update(split, part1)
121 split = c.update(split, part2)
122
123 assert full == split
124 assert full == sum_for_reflected_poly(poly, data)
125 }
126}
127
128fn test_hash_crc32_streaming_chunk_sizes() {
129 data := ('streaming data block '.repeat(64)).bytes()
130 for poly in reflected_test_polys {
131 c := crc32.new(poly)
132 expected := c.checksum(data)
133 for chunk_size in [1, 2, 3, 5, 7, 16, 31, 64, 128] {
134 mut state := ~u32(0)
135 mut start := 0
136 for start < data.len {
137 end := if start + chunk_size < data.len { start + chunk_size } else { data.len }
138 state = c.update_state(state, data[start..end])
139 start = end
140 }
141 assert ~state == expected
142 }
143 }
144}
145
146fn test_hash_crc32_update_state() {
147 data := 'stateful streaming'.bytes()
148 part1 := data[..5]
149 part2 := data[5..]
150 c := crc32.new(crc32.crc32c)
151
152 mut state := ~u32(0)
153 state = c.update_state(state, part1)
154 state = c.update_state(state, part2)
155
156 assert ~state == c.checksum(data)
157}
158