v / vlib / hash / crc64 / interop / crc64_interop.vsh
129 lines · 105 sloc · 3.18 KB · 0de4244590b0fd16cdba621a4dfa4609ebd6defc
Raw
1#!/usr/bin/env -S ./vnew run
2
3import os
4import hash.crc64
5
6struct TestVector {
7 name string
8 data []u8
9}
10
11const ecma_check_123456789 = u64(0x6c40df5f0b497347)
12
13fn compile_c_helper(dir string) string {
14 ref_c := os.join_path(dir, 'crc64_ref.c')
15 ref_bin := os.join_path(dir, 'crc64_ref')
16
17 // Compile: gcc -std=c99 crc64_ref.c -o crc64_ref
18 cmd := 'gcc -std=c99 "${ref_c}" -o "${ref_bin}"'
19 result := os.execute(cmd)
20 if result.exit_code != 0 {
21 eprintln('Failed to compile C helper:')
22 eprintln(result.output)
23 exit(1)
24 }
25
26 return ref_bin
27}
28
29fn run_c_checksum(ref_bin string, data []u8) !u64 {
30 hex_str := data.hex()
31 cmd := '${ref_bin} checksum ${hex_str}'
32 result := os.execute(cmd)
33 if result.exit_code != 0 {
34 return error('C helper failed: ${result.output}')
35 }
36
37 result_str := result.output.trim_space()
38 return u64(result_str.parse_uint(16, 64)!)
39}
40
41fn run_python_checksum(dir string, data []u8) !u64 {
42 ref_py := os.join_path(dir, 'crc64_ref.py')
43 hex_str := data.hex()
44 cmd := 'python3 "${ref_py}" checksum ${hex_str}'
45 result := os.execute(cmd)
46 if result.exit_code != 0 {
47 return error('Python helper failed: ${result.output}')
48 }
49
50 result_str := result.output.trim_space()
51 return u64(result_str.parse_uint(16, 64)!)
52}
53
54fn test_vector(name string, data []u8, ref_bin string, dir string) ! {
55 // V checksum
56 v_sum := crc64.sum(data)
57
58 // C checksum
59 c_sum := run_c_checksum(ref_bin, data)!
60
61 // Python checksum
62 py_sum := run_python_checksum(dir, data)!
63
64 // All must match
65 if v_sum != c_sum || v_sum != py_sum {
66 eprintln('FAIL: ${name}')
67 eprintln(' V: 0x${v_sum:016x}')
68 eprintln(' C: 0x${c_sum:016x}')
69 eprintln(' Python: 0x${py_sum:016x}')
70 return error('checksum mismatch')
71 }
72
73 if name == 'text_123456789' && v_sum != ecma_check_123456789 {
74 eprintln('FAIL: ${name}')
75 eprintln(' V: 0x${v_sum:016x}')
76 eprintln(' Expected: 0x${ecma_check_123456789:016x}')
77 return error('unexpected CRC-64-ECMA-182 check value')
78 }
79
80 println('OK: ${name} => 0x${v_sum:016x}')
81}
82
83fn main() {
84 dir := os.dir(@FILE)
85
86 println('Compiling C reference helper...')
87 ref_bin := compile_c_helper(dir)
88 defer { os.rm(ref_bin) or {} }
89
90 println('Running cross-validation tests...')
91 mut passed := 0
92 mut failed := 0
93
94 mut vectors := []TestVector{}
95 vectors << TestVector{'empty', []u8{}}
96 vectors << TestVector{'single_a', 'a'.bytes()}
97 vectors << TestVector{'single_null', [u8(0)]}
98 vectors << TestVector{'text_123456789', '123456789'.bytes()}
99 vectors << TestVector{'text_hello_world', 'Hello, World!'.bytes()}
100 vectors << TestVector{'all_zeros_16', []u8{len: 16}}
101 vectors << TestVector{'all_ones_16', []u8{len: 16, init: 0xFF}}
102 vectors << TestVector{'repeating_pattern', ('abc'.repeat(50)).bytes()}
103
104 mut all_bytes := []u8{len: 256}
105 for i in 0 .. 256 {
106 all_bytes[i] = u8(i)
107 }
108 vectors << TestVector{'all_bytes', all_bytes}
109 vectors << TestVector{'large_payload', ('test data '.repeat(1000)).bytes()}
110
111 for vec in vectors {
112 test_vector(vec.name, vec.data, ref_bin, dir) or {
113 eprintln(' Error: ${err}')
114 failed++
115 continue
116 }
117 passed++
118 }
119
120 println('')
121 println('=== Results ===')
122 println('Passed: ${passed}')
123 println('Failed: ${failed}')
124 println('Total: ${passed + failed}')
125
126 if failed > 0 {
127 exit(1)
128 }
129}
130