| 1 | import hash.crc64 |
| 2 | |
| 3 | fn test_crc64_basic() { |
| 4 | b1 := 'testing crc64'.bytes() |
| 5 | sum1 := crc64.sum(b1) |
| 6 | // Verify it's not zero for non-empty input |
| 7 | assert sum1 != u64(0) |
| 8 | |
| 9 | c := crc64.new(crc64.ecma) |
| 10 | b2 := 'testing crc64 again'.bytes() |
| 11 | sum2 := c.checksum(b2) |
| 12 | // Different input should yield different checksum (with high probability) |
| 13 | assert sum2 != sum1 |
| 14 | } |
| 15 | |
| 16 | fn test_crc64_empty() { |
| 17 | empty := ''.bytes() |
| 18 | assert crc64.sum(empty) == u64(0) |
| 19 | |
| 20 | c := crc64.new(crc64.ecma) |
| 21 | assert c.checksum(empty) == u64(0) |
| 22 | } |
| 23 | |
| 24 | fn test_crc64_single_byte() { |
| 25 | a := 'a'.bytes() |
| 26 | c := crc64.new(crc64.ecma) |
| 27 | sum_a := c.checksum(a) |
| 28 | assert sum_a != u64(0) |
| 29 | |
| 30 | b := 'b'.bytes() |
| 31 | sum_b := c.checksum(b) |
| 32 | assert sum_b != sum_a |
| 33 | } |
| 34 | |
| 35 | fn test_crc64_roundtrip_known_vector() { |
| 36 | // Standard test vector: "123456789" |
| 37 | data := '123456789'.bytes() |
| 38 | c := crc64.new(crc64.ecma) |
| 39 | result := c.checksum(data) |
| 40 | // CRC-64-ECMA-182 check value |
| 41 | assert result == u64(0x6c40df5f0b497347) |
| 42 | |
| 43 | // Verify consistency |
| 44 | assert crc64.sum(data) == result |
| 45 | assert crc64.sum_with_poly(crc64.ecma, data) == result |
| 46 | } |
| 47 | |
| 48 | fn test_crc64_binary_input() { |
| 49 | // Test with all byte values |
| 50 | data := [u8(0), 1, 2, 255, 128, 42, 0x00, 0xff] |
| 51 | c := crc64.new(crc64.ecma) |
| 52 | result := c.checksum(data) |
| 53 | assert result != u64(0) |
| 54 | } |
| 55 | |
| 56 | fn test_crc64_update() { |
| 57 | data := '123456789'.bytes() |
| 58 | part1 := data[..4] |
| 59 | part2 := data[4..] |
| 60 | |
| 61 | c := crc64.new(crc64.ecma) |
| 62 | mut acc := u64(0) |
| 63 | acc = c.update(acc, part1) |
| 64 | acc = c.update(acc, part2) |
| 65 | |
| 66 | assert acc == c.checksum(data) |
| 67 | } |
| 68 | |
| 69 | fn test_crc64_streaming_chunk_sizes() { |
| 70 | data := ('streaming data block '.repeat(64)).bytes() |
| 71 | c := crc64.new(crc64.ecma) |
| 72 | expected := c.checksum(data) |
| 73 | |
| 74 | for chunk_size in [1, 2, 3, 5, 7, 16, 31, 64, 128] { |
| 75 | mut state := u64(0) |
| 76 | mut start := 0 |
| 77 | for start < data.len { |
| 78 | end := if start + chunk_size < data.len { start + chunk_size } else { data.len } |
| 79 | state = c.update_state(state, data[start..end]) |
| 80 | start = end |
| 81 | } |
| 82 | assert state == expected |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | fn test_crc64_update_state() { |
| 87 | data := 'stateful streaming'.bytes() |
| 88 | part1 := data[..5] |
| 89 | part2 := data[5..] |
| 90 | c := crc64.new(crc64.ecma) |
| 91 | |
| 92 | mut state := u64(0) |
| 93 | state = c.update_state(state, part1) |
| 94 | state = c.update_state(state, part2) |
| 95 | |
| 96 | assert state == c.checksum(data) |
| 97 | } |
| 98 | |
| 99 | fn test_crc64_sum_with_poly() { |
| 100 | data := 'variant helper'.bytes() |
| 101 | c := crc64.new(crc64.ecma) |
| 102 | assert c.checksum(data) == crc64.sum_with_poly(crc64.ecma, data) |
| 103 | assert crc64.sum(data) == crc64.sum_with_poly(crc64.ecma, data) |
| 104 | } |
| 105 | |
| 106 | fn test_crc64_sum_with_poly_custom() { |
| 107 | data := 'custom poly checksum'.bytes() |
| 108 | // Use a different polynomial to verify custom path |
| 109 | poly := u64(0xa6fd4db2ef0b0da9) |
| 110 | |
| 111 | assert crc64.sum_with_poly(poly, data) == crc64.new(poly).checksum(data) |
| 112 | } |
| 113 | |
| 114 | fn test_crc64_large_input() { |
| 115 | // Test with large repetitive data |
| 116 | large_data := ('large repetitive input '.repeat(1000)).bytes() |
| 117 | c := crc64.new(crc64.ecma) |
| 118 | result := c.checksum(large_data) |
| 119 | assert result != u64(0) |
| 120 | |
| 121 | // Verify consistency with streaming |
| 122 | mut state := u64(0) |
| 123 | for i := 0; i < large_data.len; i += 512 { |
| 124 | end := if i + 512 < large_data.len { i + 512 } else { large_data.len } |
| 125 | state = c.update_state(state, large_data[i..end]) |
| 126 | } |
| 127 | assert state == result |
| 128 | } |
| 129 | |
| 130 | fn test_crc64_all_bytes() { |
| 131 | // Create data with all possible byte values |
| 132 | mut all_bytes := []u8{} |
| 133 | for b in 0 .. 256 { |
| 134 | all_bytes << u8(b) |
| 135 | } |
| 136 | c := crc64.new(crc64.ecma) |
| 137 | result := c.checksum(all_bytes) |
| 138 | assert result != u64(0) |
| 139 | |
| 140 | // Verify it's consistent |
| 141 | assert crc64.sum(all_bytes) == result |
| 142 | } |
| 143 | |
| 144 | fn test_crc64_deterministic() { |
| 145 | data := 'deterministic test'.bytes() |
| 146 | c := crc64.new(crc64.ecma) |
| 147 | |
| 148 | result1 := c.checksum(data) |
| 149 | result2 := c.checksum(data) |
| 150 | result3 := crc64.sum(data) |
| 151 | |
| 152 | assert result1 == result2 |
| 153 | assert result1 == result3 |
| 154 | } |
| 155 | |
| 156 | fn test_crc64_prefix_sensitivity() { |
| 157 | // Verify that different prefixes produce different results |
| 158 | base := 'test'.bytes() |
| 159 | c := crc64.new(crc64.ecma) |
| 160 | |
| 161 | sum_base := c.checksum(base) |
| 162 | sum_t := c.checksum('test_extended'.bytes()) |
| 163 | sum_prefix := c.checksum('prefix_test'.bytes()) |
| 164 | |
| 165 | assert sum_base != sum_t |
| 166 | assert sum_base != sum_prefix |
| 167 | assert sum_t != sum_prefix |
| 168 | } |
| 169 | |
| 170 | fn test_crc64_consistency_across_polys() { |
| 171 | // If only one poly is defined, at least verify the path works |
| 172 | data := 'poly path test'.bytes() |
| 173 | direct := crc64.sum(data) |
| 174 | via_poly := crc64.sum_with_poly(crc64.ecma, data) |
| 175 | via_new := crc64.new(crc64.ecma).checksum(data) |
| 176 | |
| 177 | assert direct == via_poly |
| 178 | assert direct == via_new |
| 179 | } |
| 180 | |