]>
Commit | Line | Data |
---|---|---|
9b0a0ba9 OZ |
1 | /* |
2 | * BIRD Library -- Fletcher-16 Tests | |
3 | * | |
4 | * (c) 2015 CZ.NIC z.s.p.o. | |
5 | * | |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #include "test/birdtest.h" | |
10 | #include "lib/fletcher16.h" | |
11 | ||
12 | static u16 | |
13 | straightforward_fletcher16_compute(const char *data) | |
14 | { | |
15 | int count = strlen(data); | |
16 | ||
17 | u16 sum1 = 0; | |
18 | u16 sum2 = 0; | |
19 | int index; | |
20 | ||
21 | for (index = 0; index < count; ++index) | |
22 | { | |
23 | sum1 = (sum1 + data[index]) % 255; | |
24 | sum2 = (sum2 + sum1) % 255; | |
25 | } | |
26 | ||
27 | return (sum2 << 8) | sum1; | |
28 | } | |
29 | ||
30 | static u16 | |
31 | straightforward_fletcher16_checksum(const char *data) | |
32 | { | |
33 | u16 csum; | |
34 | u8 c0,c1,f0,f1; | |
35 | ||
36 | csum = straightforward_fletcher16_compute(data); | |
37 | f0 = csum & 0xff; | |
38 | f1 = (csum >> 8) & 0xff; | |
39 | c0 = 0xff - ((f0 + f1) % 0xff); | |
40 | c1 = 0xff - ((f0 + c0) % 0xff); | |
41 | ||
42 | return (c1 << 8) | c0; | |
43 | } | |
44 | ||
45 | static int | |
46 | test_fletcher16(void *out_, const void *in_, const void *expected_out_) | |
47 | { | |
48 | u16 *out = out_; | |
49 | const char *in = in_; | |
50 | const u16 *expected_out = expected_out_; | |
51 | ||
52 | struct fletcher16_context ctxt; | |
53 | ||
54 | fletcher16_init(&ctxt); | |
55 | fletcher16_update(&ctxt, in, strlen(in)); | |
56 | put_u16(out, fletcher16_compute(&ctxt)); | |
57 | ||
5e3cd0e5 | 58 | return *out == *expected_out; |
9b0a0ba9 OZ |
59 | } |
60 | ||
61 | static int | |
62 | test_fletcher16_checksum(void *out_, const void *in_, const void *expected_out_) | |
63 | { | |
64 | u16 *out = out_; | |
65 | const char *in = in_; | |
66 | const u16 *expected_out = expected_out_; | |
67 | ||
68 | struct fletcher16_context ctxt; | |
69 | int len = strlen(in); | |
70 | ||
71 | fletcher16_init(&ctxt); | |
72 | fletcher16_update(&ctxt, in, len); | |
73 | put_u16(out, fletcher16_final(&ctxt, len, len)); | |
74 | ||
5e3cd0e5 | 75 | return *out == *expected_out; |
9b0a0ba9 OZ |
76 | } |
77 | ||
78 | static int | |
79 | t_fletcher16_compute(void) | |
80 | { | |
81 | struct bt_pair test_vectors[] = { | |
82 | { | |
83 | .in = "\001\002", | |
84 | .out = & (const u16) { 0x0403 }, | |
85 | }, | |
86 | { | |
87 | .in = "", | |
88 | .out = & ((const u16) { straightforward_fletcher16_compute("") }), | |
89 | }, | |
90 | { | |
91 | .in = "a", | |
92 | .out = & ((const u16) { straightforward_fletcher16_compute("a") }), | |
93 | }, | |
94 | { | |
95 | .in = "abcd", | |
96 | .out = & ((const u16) { straightforward_fletcher16_compute("abcd") }), | |
97 | }, | |
98 | { | |
99 | .in = "message digest", | |
100 | .out = & ((const u16) { straightforward_fletcher16_compute("message digest") }), | |
101 | }, | |
102 | { | |
103 | .in = "abcdefghijklmnopqrstuvwxyz", | |
104 | .out = & ((const u16) { straightforward_fletcher16_compute("abcdefghijklmnopqrstuvwxyz") }), | |
105 | }, | |
106 | { | |
107 | .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
108 | .out = & ((const u16) { straightforward_fletcher16_compute("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") }), | |
109 | }, | |
110 | { | |
111 | .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
112 | .out = & ((const u16) { straightforward_fletcher16_compute("12345678901234567890123456789012345678901234567890123456789012345678901234567890") }), | |
113 | }, | |
114 | }; | |
115 | ||
116 | return bt_assert_batch(test_vectors, test_fletcher16, bt_fmt_str, bt_fmt_unsigned); | |
117 | } | |
118 | ||
119 | static int | |
120 | t_fletcher16_checksum(void) | |
121 | { | |
122 | struct bt_pair test_vectors[] = { | |
123 | { | |
124 | .in = "\001\002", | |
125 | .out = & ((const u16) { straightforward_fletcher16_checksum("\001\002") }), | |
126 | }, | |
127 | { | |
128 | .in = "", | |
129 | .out = & ((const u16) { straightforward_fletcher16_checksum("") }), | |
130 | }, | |
131 | { | |
132 | .in = "a", | |
133 | .out = & ((const u16) { straightforward_fletcher16_checksum("a") }), | |
134 | }, | |
135 | { | |
136 | .in = "abcd", | |
137 | .out = & ((const u16) { straightforward_fletcher16_checksum("abcd") }), | |
138 | }, | |
139 | { | |
140 | .in = "message digest", | |
141 | .out = & ((const u16) { straightforward_fletcher16_checksum("message digest") }), | |
142 | }, | |
143 | { | |
144 | .in = "abcdefghijklmnopqrstuvwxyz", | |
145 | .out = & ((const u16) { straightforward_fletcher16_checksum("abcdefghijklmnopqrstuvwxyz") }), | |
146 | }, | |
147 | { | |
148 | .in = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
149 | .out = & ((const u16) { straightforward_fletcher16_checksum("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") }), | |
150 | }, | |
151 | { | |
152 | .in = "12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
153 | .out = & ((const u16) { straightforward_fletcher16_checksum("12345678901234567890123456789012345678901234567890123456789012345678901234567890") }), | |
154 | }, | |
155 | }; | |
156 | ||
157 | return bt_assert_batch(test_vectors, test_fletcher16_checksum, bt_fmt_str, bt_fmt_unsigned); | |
158 | } | |
159 | ||
160 | int | |
161 | main(int argc, char *argv[]) | |
162 | { | |
163 | bt_init(argc, argv); | |
164 | ||
165 | bt_test_suite(t_fletcher16_compute, "Fletcher-16 Compute Tests"); | |
166 | bt_test_suite(t_fletcher16_checksum, "Fletcher-16 Checksum Tests"); | |
167 | ||
168 | return bt_exit_value(); | |
169 | } |