a71ece51 |
1 | /* model.c |
2 | * Greg Cook, 9/Apr/2015 |
3 | */ |
4 | |
5 | /* CRC RevEng, an arbitrary-precision CRC calculator and algorithm finder |
6 | * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Gregory Cook |
7 | * |
8 | * This file is part of CRC RevEng. |
9 | * |
10 | * CRC RevEng is free software: you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation, either version 3 of the License, or |
13 | * (at your option) any later version. |
14 | * |
15 | * CRC RevEng is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. |
19 | * |
20 | * You should have received a copy of the GNU General Public License |
21 | * along with CRC RevEng. If not, see <http://www.gnu.org/licenses/>. |
22 | */ |
23 | |
24 | /* 2014-01-14: added CRC-8/DVB-S2 |
25 | * 2014-01-11: corrected CRC-40/GSM, added alias CRC-8/AES |
26 | * 2013-10-14: added CRC-13/BBC and six cdma2000 algorithms |
27 | * 2013-06-11: ensure BMP_BIT is an integer constant to compile presets |
28 | * 2013-01-20: big polynomials autogenerated, corrected CRC-82/DARC |
29 | * 2012-07-19: added CRC-8/EBU |
30 | * 2012-07-16: added CRC-15/MPT1327 |
31 | * 2012-05-25: removed CRC-1/PARITY-EVEN, CRC-1/PARITY-ODD |
32 | * 2012-04-12: added model CRC-31/PHILIPS |
33 | * 2012-03-03: single-line Williams model string conversion |
34 | * 2012-02-20: corrected model CRC-6/DARC |
35 | * 2011-09-03: added mrev(), mnovel() |
36 | * 2011-08-28: added model CRC-64/XZ |
37 | * 2011-04-30: added models CRC-16/TMS37157 and CRC-A, and alias CRC-B |
38 | * 2011-02-10: made preset models ANSI C compliant |
39 | * 2011-01-17: fixed ANSI C warnings (except preset models) |
40 | * 2011-01-01: added mbynum(), mcount() |
41 | * 2010-12-26: renamed CRC RevEng |
42 | * 2010-12-18: minor change to mtostr() output format |
43 | * 2010-12-15: added mcmp(), mmatch() |
44 | * 2010-12-14: finished mbynam(), mnames(), mtostr() |
45 | * 2010-12-13: restarted with PCONST macros |
46 | * 2010-12-12: was having so much fun I didn't think to try compiling. :( |
47 | * 2010-12-12: started models.c |
48 | */ |
49 | |
50 | #include <ctype.h> |
51 | #include <stdio.h> |
52 | #include <stdlib.h> |
53 | #include <string.h> |
54 | #include "reveng.h" |
55 | |
56 | /* Private declarations */ |
57 | |
58 | struct mpreset { |
59 | const unsigned long width; /* width of CRC algorithm */ |
60 | const bmp_t *const bspoly; /* polynomial with highest-order term removed. length determines CRC width */ |
61 | const bmp_t *const binit; /* initial register value. length == poly.length */ |
62 | const int flags; /* P_REFIN and P_REFOUT indicate reflected input/output */ |
63 | const bmp_t *const bxorout; /* final register XOR mask. length == poly.length */ |
64 | const bmp_t *const bcheck; /* optional check value, the CRC of the UTF-8 string "123456789" */ |
65 | const char *const name; /* optional canonical name of the model */ |
66 | }; |
67 | |
68 | struct malias { |
69 | const char *name; |
70 | const struct mpreset *model; |
71 | const int isprimry; |
72 | }; |
73 | |
74 | #ifdef PRESETS |
75 | # if BMP_BIT < 32 |
76 | # error config.h: BMP_BIT must be an integer constant macro to compile presets |
77 | # else /* BMP_BIT */ |
78 | |
79 | /* Big polynomial constants. */ |
80 | |
81 | /* Directives for relink.pl */ |
82 | /* CONSTANT b40 = (40, 0x0004820009) */ |
83 | /* CONSTANT b40a = (40, 0xffffffffff) */ |
84 | /* CONSTANT b40b = (40, 0xd4164fc646) */ |
85 | /* CONSTANT b64 = (64, 0x42f0e1eba9ea3693) */ |
86 | /* CONSTANT b64a = (64, 0x6c40df5f0b497347) */ |
87 | /* CONSTANT b64b = (64, 0xffffffffffffffff) */ |
88 | /* CONSTANT b64c = (64, 0x62ec59e3f1a4f00a) */ |
89 | /* CONSTANT b64d = (64, 0x995dc9bbdf1939fa) */ |
90 | /* CONSTANT b82 = (82, 0x0308c0111011401440411) */ |
91 | /* CONSTANT b82a = (82, 0x09ea83f625023801fd612) */ |
92 | |
93 | /* The next section was generated by relink.pl from the directives above. */ |
94 | |
95 | /* DO NOT EDIT the section below, INCLUDING the next comment. */ |
96 | /* BEGIN AUTO-GENERATED CONSTANTS */ |
97 | # if BMP_BIT >= 40 |
98 | static const bmp_t b40[] = { |
99 | BMP_C(0x0004820009) << (BMP_BIT - 40), |
100 | }; |
101 | static const bmp_t b40a[] = { |
102 | BMP_C(0xffffffffff) << (BMP_BIT - 40), |
103 | }; |
104 | static const bmp_t b40b[] = { |
105 | BMP_C(0xd4164fc646) << (BMP_BIT - 40), |
106 | }; |
107 | # else /* BMP_BIT */ |
108 | static const bmp_t b40[] = { |
109 | BMP_C(0x00048200) << (BMP_BIT - 32) | BMP_C(0x04) >> (39 - BMP_BIT), |
110 | BMP_C(0x09) << (BMP_BIT * 2 - 40), |
111 | }; |
112 | static const bmp_t b40a[] = { |
113 | BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7f) >> (39 - BMP_BIT), |
114 | BMP_C(0xff) << (BMP_BIT * 2 - 40), |
115 | }; |
116 | static const bmp_t b40b[] = { |
117 | BMP_C(0xd4164fc6) << (BMP_BIT - 32) | BMP_C(0x23) >> (39 - BMP_BIT), |
118 | BMP_C(0x46) << (BMP_BIT * 2 - 40), |
119 | }; |
120 | # endif /* BMP_BIT */ |
121 | |
122 | # if BMP_BIT >= 64 |
123 | static const bmp_t b64[] = { |
124 | BMP_C(0x42f0e1eba9ea3693) << (BMP_BIT - 64), |
125 | }; |
126 | static const bmp_t b64a[] = { |
127 | BMP_C(0x6c40df5f0b497347) << (BMP_BIT - 64), |
128 | }; |
129 | static const bmp_t b64b[] = { |
130 | BMP_C(0xffffffffffffffff) << (BMP_BIT - 64), |
131 | }; |
132 | static const bmp_t b64c[] = { |
133 | BMP_C(0x62ec59e3f1a4f00a) << (BMP_BIT - 64), |
134 | }; |
135 | static const bmp_t b64d[] = { |
136 | BMP_C(0x995dc9bbdf1939fa) << (BMP_BIT - 64), |
137 | }; |
138 | # else /* BMP_BIT */ |
139 | static const bmp_t b64[] = { |
140 | BMP_C(0x42f0e1eb) << (BMP_BIT - 32) | BMP_C(0x54f51b49) >> (63 - BMP_BIT), |
141 | BMP_C(0xa9ea3693) << (BMP_BIT * 2 - 64), |
142 | }; |
143 | static const bmp_t b64a[] = { |
144 | BMP_C(0x6c40df5f) << (BMP_BIT - 32) | BMP_C(0x05a4b9a3) >> (63 - BMP_BIT), |
145 | BMP_C(0x0b497347) << (BMP_BIT * 2 - 64), |
146 | }; |
147 | static const bmp_t b64b[] = { |
148 | BMP_C(0xffffffff) << (BMP_BIT - 32) | BMP_C(0x7fffffff) >> (63 - BMP_BIT), |
149 | BMP_C(0xffffffff) << (BMP_BIT * 2 - 64), |
150 | }; |
151 | static const bmp_t b64c[] = { |
152 | BMP_C(0x62ec59e3) << (BMP_BIT - 32) | BMP_C(0x78d27805) >> (63 - BMP_BIT), |
153 | BMP_C(0xf1a4f00a) << (BMP_BIT * 2 - 64), |
154 | }; |
155 | static const bmp_t b64d[] = { |
156 | BMP_C(0x995dc9bb) << (BMP_BIT - 32) | BMP_C(0x6f8c9cfd) >> (63 - BMP_BIT), |
157 | BMP_C(0xdf1939fa) << (BMP_BIT * 2 - 64), |
158 | }; |
159 | # endif /* BMP_BIT */ |
160 | |
161 | # if BMP_BIT >= 82 |
162 | static const bmp_t b82[] = { |
163 | BMP_C(0x0308c0111011401440411) << (BMP_BIT - 82), |
164 | }; |
165 | static const bmp_t b82a[] = { |
166 | BMP_C(0x09ea83f625023801fd612) << (BMP_BIT - 82), |
167 | }; |
168 | # elif BMP_BIT >= 41 |
169 | static const bmp_t b82[] = { |
170 | BMP_C(0x01846008880) << (BMP_BIT - 41) | BMP_C(0x08a00a20208) >> (81 - BMP_BIT), |
171 | BMP_C(0x11401440411) << (BMP_BIT * 2 - 82), |
172 | }; |
173 | static const bmp_t b82a[] = { |
174 | BMP_C(0x04f541fb128) << (BMP_BIT - 41) | BMP_C(0x011c00feb09) >> (81 - BMP_BIT), |
175 | BMP_C(0x023801fd612) << (BMP_BIT * 2 - 82), |
176 | }; |
177 | # else /* BMP_BIT */ |
178 | static const bmp_t b82[] = { |
179 | BMP_C(0x0c230044) << (BMP_BIT - 32) | BMP_C(0x040) >> (40 - BMP_BIT), |
180 | BMP_C(0x40450051) << (BMP_BIT * 2 - 64) | BMP_C(0x00104) >> (80 - BMP_BIT * 2), |
181 | BMP_C(0x00411) << (BMP_BIT * 3 - 82), |
182 | }; |
183 | static const bmp_t b82a[] = { |
184 | BMP_C(0x27aa0fd8) << (BMP_BIT - 32) | BMP_C(0x094) >> (40 - BMP_BIT), |
185 | BMP_C(0x9408e007) << (BMP_BIT * 2 - 64) | BMP_C(0x0f584) >> (80 - BMP_BIT * 2), |
186 | BMP_C(0x3d612) << (BMP_BIT * 3 - 82), |
187 | }; |
188 | # endif /* BMP_BIT */ |
189 | |
190 | /* END AUTO-GENERATED CONSTANTS */ |
191 | /* DO NOT EDIT the section above, INCLUDING the previous comment. */ |
192 | |
193 | /* Array of the polynomial bitmaps used in the model table. */ |
194 | static const bmp_t b32[] = { |
195 | BMP_C(0x00000000) << (BMP_BIT - 32), /* 0 -- 5, 00 */ |
196 | BMP_C(0x000000af) << (BMP_BIT - 32), /* 1 -- 32,000000af */ |
197 | BMP_C(0x00010000) << (BMP_BIT - 32), /* 2 -- 16, 0001 */ |
198 | BMP_C(0x00020000) << (BMP_BIT - 32), /* 3 -- 15, 0001 */ |
199 | BMP_C(0x007e0000) << (BMP_BIT - 32), /* 4 -- 16, 007e */ |
200 | BMP_C(0x007f0000) << (BMP_BIT - 32), /* 5 -- 16, 007f */ |
201 | BMP_C(0x03400000) << (BMP_BIT - 32), /* 6 -- 11, 01a */ |
202 | BMP_C(0x0376e6e7) << (BMP_BIT - 32), /* 7 -- 32,0376e6e7 */ |
203 | BMP_C(0x04c11db7) << (BMP_BIT - 32), /* 8 -- 32,04c11db7 */ |
204 | BMP_C(0x05890000) << (BMP_BIT - 32), /* 9 -- 16, 0589 */ |
205 | BMP_C(0x07000000) << (BMP_BIT - 32), /* 10 -- 8, 07 */ |
206 | BMP_C(0x09823b6e) << (BMP_BIT - 32), /* 11 -- 31,04c11db7 */ |
207 | BMP_C(0x0b3c0000) << (BMP_BIT - 32), /* 12 -- 15, 059e */ |
208 | BMP_C(0x0c000000) << (BMP_BIT - 32), /* 13 -- 6, 03 */ |
209 | BMP_C(0x0fb30000) << (BMP_BIT - 32), /* 14 -- 16, 0fb3 */ |
210 | BMP_C(0x10210000) << (BMP_BIT - 32), /* 15 -- 16, 1021 */ |
211 | BMP_C(0x12000000) << (BMP_BIT - 32), /* 16 -- 7, 09 */ |
212 | BMP_C(0x15000000) << (BMP_BIT - 32), /* 17 -- 8, 15 */ |
213 | BMP_C(0x18000000) << (BMP_BIT - 32), /* 18 -- 6, 06 */ |
214 | BMP_C(0x19d3c8d8) << (BMP_BIT - 32), /* 19 -- 31,0ce9e46c */ |
215 | BMP_C(0x1c000000) << (BMP_BIT - 32), /* 20 -- 6, 07 */ |
216 | BMP_C(0x1d000000) << (BMP_BIT - 32), /* 21 -- 8, 1d */ |
217 | BMP_C(0x1d0f0000) << (BMP_BIT - 32), /* 22 -- 16, 1d0f */ |
218 | BMP_C(0x1edc6f41) << (BMP_BIT - 32), /* 23 -- 32,1edc6f41 */ |
219 | BMP_C(0x1f23b800) << (BMP_BIT - 32), /* 24 -- 24, 1f23b8 */ |
220 | BMP_C(0x20140000) << (BMP_BIT - 32), /* 25 -- 14, 0805 */ |
221 | BMP_C(0x20b40000) << (BMP_BIT - 32), /* 26 -- 14, 082d */ |
222 | BMP_C(0x21890000) << (BMP_BIT - 32), /* 27 -- 16, 2189 */ |
223 | BMP_C(0x21cf0200) << (BMP_BIT - 32), /* 28 -- 24, 21cf02 */ |
224 | BMP_C(0x25000000) << (BMP_BIT - 32), /* 29 -- 8, 25 */ |
225 | BMP_C(0x26b10000) << (BMP_BIT - 32), /* 30 -- 16, 26b1 */ |
226 | BMP_C(0x27d00000) << (BMP_BIT - 32), /* 31 -- 13, 04fa */ |
227 | BMP_C(0x28000000) << (BMP_BIT - 32), /* 32 -- 5, 05 */ |
228 | BMP_C(0x29b10000) << (BMP_BIT - 32), /* 33 -- 16, 29b1 */ |
229 | BMP_C(0x30000000) << (BMP_BIT - 32), /* 34 -- 4, 3 */ |
230 | BMP_C(0x3010bf7f) << (BMP_BIT - 32), /* 35 -- 32,3010bf7f */ |
231 | BMP_C(0x31000000) << (BMP_BIT - 32), /* 36 -- 8, 31 */ |
232 | BMP_C(0x31c30000) << (BMP_BIT - 32), /* 37 -- 16, 31c3 */ |
233 | BMP_C(0x34000000) << (BMP_BIT - 32), /* 38 -- 6, 0d */ |
234 | BMP_C(0x340bc6d9) << (BMP_BIT - 32), /* 39 -- 32,340bc6d9 */ |
235 | BMP_C(0x38000000) << (BMP_BIT - 32), /* 40 -- 5, 07 */ |
236 | BMP_C(0x39000000) << (BMP_BIT - 32), /* 41 -- 8, 39 */ |
237 | BMP_C(0x3d650000) << (BMP_BIT - 32), /* 42 -- 16, 3d65 */ |
238 | BMP_C(0x44c20000) << (BMP_BIT - 32), /* 43 -- 16, 44c2 */ |
239 | BMP_C(0x48000000) << (BMP_BIT - 32), /* 44 -- 5, 09 */ |
240 | BMP_C(0x4acc0000) << (BMP_BIT - 32), /* 45 -- 15, 2566 */ |
241 | BMP_C(0x4b370000) << (BMP_BIT - 32), /* 46 -- 16, 4b37 */ |
242 | BMP_C(0x4c060000) << (BMP_BIT - 32), /* 47 -- 16, 4c06 */ |
243 | BMP_C(0x55000000) << (BMP_BIT - 32), /* 48 -- 8, 55 */ |
244 | BMP_C(0x5d6dcb00) << (BMP_BIT - 32), /* 49 -- 24, 5d6dcb */ |
245 | BMP_C(0x60000000) << (BMP_BIT - 32), /* 50 -- 3, 3 */ |
246 | BMP_C(0x63d00000) << (BMP_BIT - 32), /* 51 -- 16, 63d0 */ |
247 | BMP_C(0x64000000) << (BMP_BIT - 32), /* 52 -- 6, 19 */ |
248 | BMP_C(0x66400000) << (BMP_BIT - 32), /* 53 -- 10, 199 */ |
249 | BMP_C(0x6f910000) << (BMP_BIT - 32), /* 54 -- 16, 6f91 */ |
250 | BMP_C(0x70000000) << (BMP_BIT - 32), /* 55 -- 4, 7 */ |
251 | BMP_C(0x70a00000) << (BMP_BIT - 32), /* 56 -- 11, 385 */ |
252 | BMP_C(0x765e7680) << (BMP_BIT - 32), /* 57 -- 32,765e7680 */ |
253 | BMP_C(0x7979bd00) << (BMP_BIT - 32), /* 58 -- 24, 7979bd */ |
254 | BMP_C(0x7e000000) << (BMP_BIT - 32), /* 59 -- 8, 7e */ |
255 | BMP_C(0x80050000) << (BMP_BIT - 32), /* 60 -- 16, 8005 */ |
256 | BMP_C(0x800d0000) << (BMP_BIT - 32), /* 61 -- 16, 800d */ |
257 | BMP_C(0x80f00000) << (BMP_BIT - 32), /* 62 -- 12, 80f */ |
258 | BMP_C(0x814141ab) << (BMP_BIT - 32), /* 63 -- 32,814141ab */ |
259 | BMP_C(0x864cfb00) << (BMP_BIT - 32), /* 64 -- 24, 864cfb */ |
260 | BMP_C(0x87315576) << (BMP_BIT - 32), /* 65 -- 32,87315576 */ |
261 | BMP_C(0x89ec0000) << (BMP_BIT - 32), /* 66 -- 16, 89ec */ |
262 | BMP_C(0x8b320000) << (BMP_BIT - 32), /* 67 -- 15, 4599 */ |
263 | BMP_C(0x8bb70000) << (BMP_BIT - 32), /* 68 -- 16, 8bb7 */ |
264 | BMP_C(0x8cc00000) << (BMP_BIT - 32), /* 69 -- 10, 233 */ |
265 | BMP_C(0x906e0000) << (BMP_BIT - 32), /* 70 -- 16, 906e */ |
266 | BMP_C(0x97000000) << (BMP_BIT - 32), /* 71 -- 8, 97 */ |
267 | BMP_C(0x98000000) << (BMP_BIT - 32), /* 72 -- 6, 26 */ |
268 | BMP_C(0x9b000000) << (BMP_BIT - 32), /* 73 -- 8, 9b */ |
269 | BMP_C(0x9c000000) << (BMP_BIT - 32), /* 74 -- 6, 27 */ |
270 | BMP_C(0x9e000000) << (BMP_BIT - 32), /* 75 -- 7, 4f */ |
271 | BMP_C(0x9ecf0000) << (BMP_BIT - 32), /* 76 -- 16, 9ecf */ |
272 | BMP_C(0xa0970000) << (BMP_BIT - 32), /* 77 -- 16, a097 */ |
273 | BMP_C(0xa1000000) << (BMP_BIT - 32), /* 78 -- 8, a1 */ |
274 | BMP_C(0xa6000000) << (BMP_BIT - 32), /* 79 -- 7, 53 */ |
275 | BMP_C(0xa8000000) << (BMP_BIT - 32), /* 80 -- 5, 15 */ |
276 | BMP_C(0xa833982b) << (BMP_BIT - 32), /* 81 -- 32,a833982b */ |
277 | BMP_C(0xabcdef00) << (BMP_BIT - 32), /* 82 -- 24, abcdef */ |
278 | BMP_C(0xb2aa0000) << (BMP_BIT - 32), /* 83 -- 16, b2aa */ |
279 | BMP_C(0xb4600000) << (BMP_BIT - 32), /* 84 -- 11, 5a3 */ |
280 | BMP_C(0xb4c80000) << (BMP_BIT - 32), /* 85 -- 16, b4c8 */ |
281 | BMP_C(0xb704ce00) << (BMP_BIT - 32), /* 86 -- 24, b704ce */ |
282 | BMP_C(0xbb3d0000) << (BMP_BIT - 32), /* 87 -- 16, bb3d */ |
283 | BMP_C(0xbc000000) << (BMP_BIT - 32), /* 88 -- 8, bc */ |
284 | BMP_C(0xbd0be338) << (BMP_BIT - 32), /* 89 -- 32,bd0be338 */ |
285 | BMP_C(0xbf050000) << (BMP_BIT - 32), /* 90 -- 16, bf05 */ |
286 | BMP_C(0xc0000000) << (BMP_BIT - 32), /* 91 -- 3, 6 */ |
287 | BMP_C(0xc2b70000) << (BMP_BIT - 32), /* 92 -- 16, c2b7 */ |
288 | BMP_C(0xc6c60000) << (BMP_BIT - 32), /* 93 -- 16, c6c6 */ |
289 | BMP_C(0xc8000000) << (BMP_BIT - 32), /* 94 -- 5, 19 */ |
290 | BMP_C(0xc8670000) << (BMP_BIT - 32), /* 95 -- 16, c867 */ |
291 | BMP_C(0xcbf43926) << (BMP_BIT - 32), /* 96 -- 32,cbf43926 */ |
292 | BMP_C(0xd0000000) << (BMP_BIT - 32), /* 97 -- 8, d0 */ |
293 | BMP_C(0xd02a0000) << (BMP_BIT - 32), /* 98 -- 15, 6815 */ |
294 | BMP_C(0xd0db0000) << (BMP_BIT - 32), /* 99 -- 16, d0db */ |
295 | BMP_C(0xd4d00000) << (BMP_BIT - 32), /* 100 -- 12, d4d */ |
296 | BMP_C(0xd5000000) << (BMP_BIT - 32), /* 101 -- 8, d5 */ |
297 | BMP_C(0xd64e0000) << (BMP_BIT - 32), /* 102 -- 16, d64e */ |
298 | BMP_C(0xda000000) << (BMP_BIT - 32), /* 103 -- 8, da */ |
299 | BMP_C(0xdaf00000) << (BMP_BIT - 32), /* 104 -- 12, daf */ |
300 | BMP_C(0xe0000000) << (BMP_BIT - 32), /* 105 -- 3, 7 */ |
301 | BMP_C(0xe3069283) << (BMP_BIT - 32), /* 106 -- 32,e3069283 */ |
302 | BMP_C(0xe5cc0000) << (BMP_BIT - 32), /* 107 -- 16, e5cc */ |
303 | BMP_C(0xe7a80000) << (BMP_BIT - 32), /* 108 -- 13, 1cf5 */ |
304 | BMP_C(0xea000000) << (BMP_BIT - 32), /* 109 -- 7, 75 */ |
305 | BMP_C(0xea820000) << (BMP_BIT - 32), /* 110 -- 16, ea82 */ |
306 | BMP_C(0xec000000) << (BMP_BIT - 32), /* 111 -- 6, 3b */ |
307 | BMP_C(0xf1300000) << (BMP_BIT - 32), /* 112 -- 12, f13 */ |
308 | BMP_C(0xf4000000) << (BMP_BIT - 32), /* 113 -- 8, f4 */ |
309 | BMP_C(0xf5b00000) << (BMP_BIT - 32), /* 114 -- 12, f5b */ |
310 | BMP_C(0xf6400000) << (BMP_BIT - 32), /* 115 -- 10, 3d9 */ |
311 | BMP_C(0xf8000000) << (BMP_BIT - 32), /* 116 -- 5, 1f */ |
312 | BMP_C(0xfc000000) << (BMP_BIT - 32), /* 117 -- 6, 3f */ |
313 | BMP_C(0xfc891918) << (BMP_BIT - 32), /* 118 -- 32,fc891918 */ |
314 | BMP_C(0xfd000000) << (BMP_BIT - 32), /* 119 -- 8, fd */ |
315 | BMP_C(0xfe000000) << (BMP_BIT - 32), /* 120 -- 7, 7f */ |
316 | BMP_C(0xfedcba00) << (BMP_BIT - 32), /* 121 -- 24, fedcba */ |
317 | BMP_C(0xfee80000) << (BMP_BIT - 32), /* 122 -- 16, fee8 */ |
318 | BMP_C(0xff000000) << (BMP_BIT - 32), /* 123 -- 8, ff */ |
319 | BMP_C(0xffc00000) << (BMP_BIT - 32), /* 124 -- 10, 3ff */ |
320 | BMP_C(0xfff00000) << (BMP_BIT - 32), /* 125 -- 12, fff */ |
321 | BMP_C(0xffff0000) << (BMP_BIT - 32), /* 126 -- 16, ffff */ |
322 | BMP_C(0xfffffffe) << (BMP_BIT - 32), /* 127 -- 31,7fffffff */ |
323 | BMP_C(0xffffffff) << (BMP_BIT - 32), /* 128 -- 32,ffffffff */ |
324 | }; |
325 | |
326 | /* Table of preset CRC models. |
327 | * Sorted by left-justified polynomial for bsearch(). |
328 | */ |
329 | static const struct mpreset models[] = { |
330 | {32UL, b32+ 1, 0, P_BE, 0, b32+ 89, "XFER" }, /* 0 */ |
331 | {40UL, b40, 0, P_BE, b40a, b40b, "CRC-40/GSM" }, /* 1 */ |
332 | {32UL, b32+ 8, 0, P_BE, b32+128, b32+ 57, "CRC-32/POSIX" }, /* 2 */ |
333 | {32UL, b32+ 8, b32+128, P_BE, 0, b32+ 7, "CRC-32/MPEG-2" }, /* 3 */ |
334 | {32UL, b32+ 8, b32+128, P_BE, b32+128, b32+118, "CRC-32/BZIP2" }, /* 4 */ |
335 | {32UL, b32+ 8, b32+128, P_LE, 0, b32+ 39, "JAMCRC" }, /* 5 */ |
336 | {32UL, b32+ 8, b32+128, P_LE, b32+128, b32+ 96, "CRC-32" }, /* 6 */ |
337 | {16UL, b32+ 9, 0, P_BE, 0, b32+ 5, "CRC-16/DECT-X" }, /* 7 */ |
338 | {16UL, b32+ 9, 0, P_BE, b32+ 2, b32+ 4, "CRC-16/DECT-R" }, /* 8 */ |
339 | { 8UL, b32+ 10, 0, P_BE, 0, b32+113, "CRC-8" }, /* 9 */ |
340 | { 8UL, b32+ 10, 0, P_BE, b32+ 48, b32+ 78, "CRC-8/ITU" }, /* 10 */ |
341 | { 8UL, b32+ 10, b32+123, P_LE, 0, b32+ 97, "CRC-8/ROHC" }, /* 11 */ |
342 | {31UL, b32+ 11, b32+127, P_BE, b32+127, b32+ 19, "CRC-31/PHILIPS" }, /* 12 */ |
343 | { 6UL, b32+ 13, 0, P_LE, 0, b32+ 18, "CRC-6/ITU" }, /* 13 */ |
344 | {82UL, b82, 0, P_LE, 0, b82a, "CRC-82/DARC" }, /* 14 */ |
345 | {16UL, b32+ 15, 0, P_BE, 0, b32+ 37, "XMODEM" }, /* 15 */ |
346 | {16UL, b32+ 15, 0, P_LE, 0, b32+ 27, "KERMIT" }, /* 16 */ |
347 | {16UL, b32+ 15, b32+ 22, P_BE, 0, b32+107, "CRC-16/AUG-CCITT" }, /* 17 */ |
348 | {16UL, b32+ 15, b32+ 66, P_LE, 0, b32+ 30, "CRC-16/TMS37157" }, /* 18 */ |
349 | {16UL, b32+ 15, b32+ 83, P_LE, 0, b32+ 51, "CRC-16/RIELLO" }, /* 19 */ |
350 | {16UL, b32+ 15, b32+ 93, P_LE, 0, b32+ 90, "CRC-A" }, /* 20 */ |
351 | {16UL, b32+ 15, b32+126, P_BE, 0, b32+ 33, "CRC-16/CCITT-FALSE"}, /* 21 */ |
352 | {16UL, b32+ 15, b32+126, P_BE, b32+126, b32+102, "CRC-16/GENIBUS" }, /* 22 */ |
353 | {16UL, b32+ 15, b32+126, P_LE, 0, b32+ 54, "CRC-16/MCRF4XX" }, /* 23 */ |
354 | {16UL, b32+ 15, b32+126, P_LE, b32+126, b32+ 70, "X-25" }, /* 24 */ |
355 | { 7UL, b32+ 16, 0, P_BE, 0, b32+109, "CRC-7" }, /* 25 */ |
356 | { 6UL, b32+ 20, b32+117, P_BE, 0, b32+111, "CRC-6/CDMA2000-B" }, /* 26 */ |
357 | { 8UL, b32+ 21, b32+119, P_BE, 0, b32+ 59, "CRC-8/I-CODE" }, /* 27 */ |
358 | { 8UL, b32+ 21, b32+123, P_LE, 0, b32+ 71, "CRC-8/EBU" }, /* 28 */ |
359 | {32UL, b32+ 23, b32+128, P_LE, b32+128, b32+106, "CRC-32C" }, /* 29 */ |
360 | {14UL, b32+ 25, 0, P_LE, 0, b32+ 26, "CRC-14/DARC" }, /* 30 */ |
361 | { 5UL, b32+ 32, b32+116, P_LE, b32+116, b32+ 94, "CRC-5/USB" }, /* 31 */ |
362 | { 4UL, b32+ 34, 0, P_LE, 0, b32+ 55, "CRC-4/ITU" }, /* 32 */ |
363 | { 8UL, b32+ 36, 0, P_LE, 0, b32+ 78, "CRC-8/MAXIM" }, /* 33 */ |
364 | { 8UL, b32+ 41, 0, P_LE, 0, b32+ 17, "CRC-8/DARC" }, /* 34 */ |
365 | {16UL, b32+ 42, 0, P_BE, b32+126, b32+ 92, "CRC-16/EN-13757" }, /* 35 */ |
366 | {16UL, b32+ 42, 0, P_LE, b32+126, b32+110, "CRC-16/DNP" }, /* 36 */ |
367 | {64UL, b64, 0, P_BE, 0, b64a, "CRC-64" }, /* 37 */ |
368 | {64UL, b64, b64b, P_BE, b64b, b64c, "CRC-64/WE" }, /* 38 */ |
369 | {64UL, b64, b64b, P_LE, b64b, b64d, "CRC-64/XZ" }, /* 39 */ |
370 | { 5UL, b32+ 44, b32+ 44, P_BE, 0, b32+ 0, "CRC-5/EPC" }, /* 40 */ |
371 | {24UL, b32+ 49, b32+ 82, P_BE, 0, b32+ 24, "CRC-24/FLEXRAY-B" }, /* 41 */ |
372 | {24UL, b32+ 49, b32+121, P_BE, 0, b32+ 58, "CRC-24/FLEXRAY-A" }, /* 42 */ |
373 | { 3UL, b32+ 50, b32+105, P_LE, 0, b32+ 91, "CRC-3/ROHC" }, /* 43 */ |
374 | { 6UL, b32+ 52, 0, P_LE, 0, b32+ 72, "CRC-6/DARC" }, /* 44 */ |
375 | {11UL, b32+ 56, b32+ 6, P_BE, 0, b32+ 84, "CRC-11" }, /* 45 */ |
376 | {16UL, b32+ 60, 0, P_BE, 0, b32+122, "CRC-16/BUYPASS" }, /* 46 */ |
377 | {16UL, b32+ 60, 0, P_LE, 0, b32+ 87, "ARC" }, /* 47 */ |
378 | {16UL, b32+ 60, 0, P_LE, b32+126, b32+ 43, "CRC-16/MAXIM" }, /* 48 */ |
379 | {16UL, b32+ 60, b32+ 61, P_BE, 0, b32+ 76, "CRC-16/DDS-110" }, /* 49 */ |
380 | {16UL, b32+ 60, b32+126, P_LE, 0, b32+ 46, "MODBUS" }, /* 50 */ |
381 | {16UL, b32+ 60, b32+126, P_LE, b32+126, b32+ 85, "CRC-16/USB" }, /* 51 */ |
382 | {12UL, b32+ 62, 0, P_BE, 0, b32+114, "CRC-12/DECT" }, /* 52 */ |
383 | {12UL, b32+ 62, 0, P_BELE, 0, b32+104, "CRC-12/3GPP" }, /* 53 */ |
384 | {32UL, b32+ 63, 0, P_BE, 0, b32+ 35, "CRC-32Q" }, /* 54 */ |
385 | {24UL, b32+ 64, b32+ 86, P_BE, 0, b32+ 28, "CRC-24" }, /* 55 */ |
386 | {15UL, b32+ 67, 0, P_BE, 0, b32+ 12, "CRC-15" }, /* 56 */ |
387 | {16UL, b32+ 68, 0, P_BE, 0, b32+ 99, "CRC-16/T10-DIF" }, /* 57 */ |
388 | {10UL, b32+ 69, 0, P_BE, 0, b32+ 53, "CRC-10" }, /* 58 */ |
389 | { 8UL, b32+ 73, 0, P_LE, 0, b32+ 29, "CRC-8/WCDMA" }, /* 59 */ |
390 | { 8UL, b32+ 73, b32+123, P_BE, 0, b32+103, "CRC-8/CDMA2000" }, /* 60 */ |
391 | { 6UL, b32+ 74, b32+117, P_BE, 0, b32+ 38, "CRC-6/CDMA2000-A" }, /* 61 */ |
392 | { 7UL, b32+ 75, b32+120, P_LE, 0, b32+ 79, "CRC-7/ROHC" }, /* 62 */ |
393 | {16UL, b32+ 77, 0, P_BE, 0, b32+ 14, "CRC-16/TELEDISK" }, /* 63 */ |
394 | { 5UL, b32+ 80, 0, P_LE, 0, b32+ 40, "CRC-5/ITU" }, /* 64 */ |
395 | {32UL, b32+ 81, b32+128, P_LE, b32+128, b32+ 65, "CRC-32D" }, /* 65 */ |
396 | {16UL, b32+ 95, b32+126, P_BE, 0, b32+ 47, "CRC-16/CDMA2000" }, /* 66 */ |
397 | {15UL, b32+ 98, 0, P_BE, b32+ 3, b32+ 45, "CRC-15/MPT1327" }, /* 67 */ |
398 | { 8UL, b32+101, 0, P_BE, 0, b32+ 88, "CRC-8/DVB-S2" }, /* 68 */ |
399 | {13UL, b32+108, 0, P_BE, 0, b32+ 31, "CRC-13/BBC" }, /* 69 */ |
400 | {12UL, b32+112, b32+125, P_BE, 0, b32+100, "CRC-12/CDMA2000" }, /* 70 */ |
401 | {10UL, b32+115, b32+124, P_BE, 0, b32+ 69, "CRC-10/CDMA2000" }, /* 71 */ |
402 | }; |
403 | # define NPRESETS 72 |
404 | |
405 | /* List of names with pointers to models, pre-sorted for use with bsearch() */ |
406 | static const struct malias aliases[] = { |
407 | {"ARC", models+47, 1}, /* 0 */ |
408 | {"B-CRC-32", models+ 4, 0}, /* 1 */ |
409 | {"CKSUM", models+ 2, 0}, /* 2 */ |
410 | {"CRC-10", models+58, 1}, /* 3 */ |
411 | {"CRC-10/CDMA2000", models+71, 1}, /* 4 */ |
412 | {"CRC-11", models+45, 1}, /* 5 */ |
413 | {"CRC-12/3GPP", models+53, 1}, /* 6 */ |
414 | {"CRC-12/CDMA2000", models+70, 1}, /* 7 */ |
415 | {"CRC-12/DECT", models+52, 1}, /* 8 */ |
416 | {"CRC-13/BBC", models+69, 1}, /* 9 */ |
417 | {"CRC-14/DARC", models+30, 1}, /* 10 */ |
418 | {"CRC-15", models+56, 1}, /* 11 */ |
419 | {"CRC-15/MPT1327", models+67, 1}, /* 12 */ |
420 | {"CRC-16", models+47, 0}, /* 13 */ |
421 | {"CRC-16/ACORN", models+15, 0}, /* 14 */ |
422 | {"CRC-16/ARC", models+47, 0}, /* 15 */ |
423 | {"CRC-16/AUG-CCITT", models+17, 1}, /* 16 */ |
424 | {"CRC-16/BUYPASS", models+46, 1}, /* 17 */ |
425 | {"CRC-16/CCITT", models+16, 0}, /* 18 */ |
426 | {"CRC-16/CCITT-FALSE", models+21, 1}, /* 19 */ |
427 | {"CRC-16/CCITT-TRUE", models+16, 0}, /* 20 */ |
428 | {"CRC-16/CDMA2000", models+66, 1}, /* 21 */ |
429 | {"CRC-16/DARC", models+22, 0}, /* 22 */ |
430 | {"CRC-16/DDS-110", models+49, 1}, /* 23 */ |
431 | {"CRC-16/DECT-R", models+ 8, 1}, /* 24 */ |
432 | {"CRC-16/DECT-X", models+ 7, 1}, /* 25 */ |
433 | {"CRC-16/DNP", models+36, 1}, /* 26 */ |
434 | {"CRC-16/EN-13757", models+35, 1}, /* 27 */ |
435 | {"CRC-16/EPC", models+22, 0}, /* 28 */ |
436 | {"CRC-16/GENIBUS", models+22, 1}, /* 29 */ |
437 | {"CRC-16/I-CODE", models+22, 0}, /* 30 */ |
438 | {"CRC-16/IBM-SDLC", models+24, 0}, /* 31 */ |
439 | {"CRC-16/ISO-HDLC", models+24, 0}, /* 32 */ |
440 | {"CRC-16/LHA", models+47, 0}, /* 33 */ |
441 | {"CRC-16/MAXIM", models+48, 1}, /* 34 */ |
442 | {"CRC-16/MCRF4XX", models+23, 1}, /* 35 */ |
443 | {"CRC-16/RIELLO", models+19, 1}, /* 36 */ |
444 | {"CRC-16/SPI-FUJITSU", models+17, 0}, /* 37 */ |
445 | {"CRC-16/T10-DIF", models+57, 1}, /* 38 */ |
446 | {"CRC-16/TELEDISK", models+63, 1}, /* 39 */ |
447 | {"CRC-16/TMS37157", models+18, 1}, /* 40 */ |
448 | {"CRC-16/USB", models+51, 1}, /* 41 */ |
449 | {"CRC-16/VERIFONE", models+46, 0}, /* 42 */ |
450 | {"CRC-24", models+55, 1}, /* 43 */ |
451 | {"CRC-24/FLEXRAY-A", models+42, 1}, /* 44 */ |
452 | {"CRC-24/FLEXRAY-B", models+41, 1}, /* 45 */ |
453 | {"CRC-24/OPENPGP", models+55, 0}, /* 46 */ |
454 | {"CRC-3/ROHC", models+43, 1}, /* 47 */ |
455 | {"CRC-31/PHILIPS", models+12, 1}, /* 48 */ |
456 | {"CRC-32", models+ 6, 1}, /* 49 */ |
457 | {"CRC-32/AAL5", models+ 4, 0}, /* 50 */ |
458 | {"CRC-32/ADCCP", models+ 6, 0}, /* 51 */ |
459 | {"CRC-32/BZIP2", models+ 4, 1}, /* 52 */ |
460 | {"CRC-32/CASTAGNOLI", models+29, 0}, /* 53 */ |
461 | {"CRC-32/DECT-B", models+ 4, 0}, /* 54 */ |
462 | {"CRC-32/ISCSI", models+29, 0}, /* 55 */ |
463 | {"CRC-32/MPEG-2", models+ 3, 1}, /* 56 */ |
464 | {"CRC-32/POSIX", models+ 2, 1}, /* 57 */ |
465 | {"CRC-32C", models+29, 1}, /* 58 */ |
466 | {"CRC-32D", models+65, 1}, /* 59 */ |
467 | {"CRC-32Q", models+54, 1}, /* 60 */ |
468 | {"CRC-4/ITU", models+32, 1}, /* 61 */ |
469 | {"CRC-40/GSM", models+ 1, 1}, /* 62 */ |
470 | {"CRC-5/EPC", models+40, 1}, /* 63 */ |
471 | {"CRC-5/ITU", models+64, 1}, /* 64 */ |
472 | {"CRC-5/USB", models+31, 1}, /* 65 */ |
473 | {"CRC-6/CDMA2000-A", models+61, 1}, /* 66 */ |
474 | {"CRC-6/CDMA2000-B", models+26, 1}, /* 67 */ |
475 | {"CRC-6/DARC", models+44, 1}, /* 68 */ |
476 | {"CRC-6/ITU", models+13, 1}, /* 69 */ |
477 | {"CRC-64", models+37, 1}, /* 70 */ |
478 | {"CRC-64/WE", models+38, 1}, /* 71 */ |
479 | {"CRC-64/XZ", models+39, 1}, /* 72 */ |
480 | {"CRC-7", models+25, 1}, /* 73 */ |
481 | {"CRC-7/ROHC", models+62, 1}, /* 74 */ |
482 | {"CRC-8", models+ 9, 1}, /* 75 */ |
483 | {"CRC-8/AES", models+28, 0}, /* 76 */ |
484 | {"CRC-8/CDMA2000", models+60, 1}, /* 77 */ |
485 | {"CRC-8/DARC", models+34, 1}, /* 78 */ |
486 | {"CRC-8/DVB-S2", models+68, 1}, /* 79 */ |
487 | {"CRC-8/EBU", models+28, 1}, /* 80 */ |
488 | {"CRC-8/I-CODE", models+27, 1}, /* 81 */ |
489 | {"CRC-8/ITU", models+10, 1}, /* 82 */ |
490 | {"CRC-8/MAXIM", models+33, 1}, /* 83 */ |
491 | {"CRC-8/ROHC", models+11, 1}, /* 84 */ |
492 | {"CRC-8/WCDMA", models+59, 1}, /* 85 */ |
493 | {"CRC-82/DARC", models+14, 1}, /* 86 */ |
494 | {"CRC-A", models+20, 1}, /* 87 */ |
495 | {"CRC-B", models+24, 0}, /* 88 */ |
496 | {"CRC-CCITT", models+16, 0}, /* 89 */ |
497 | {"CRC-IBM", models+47, 0}, /* 90 */ |
498 | {"DOW-CRC", models+33, 0}, /* 91 */ |
499 | {"JAMCRC", models+ 5, 1}, /* 92 */ |
500 | {"KERMIT", models+16, 1}, /* 93 */ |
501 | {"MODBUS", models+50, 1}, /* 94 */ |
502 | {"PKZIP", models+ 6, 0}, /* 95 */ |
503 | {"R-CRC-16", models+ 8, 0}, /* 96 */ |
504 | {"X-25", models+24, 1}, /* 97 */ |
505 | {"X-CRC-12", models+52, 0}, /* 98 */ |
506 | {"X-CRC-16", models+ 7, 0}, /* 99 */ |
507 | {"XFER", models+ 0, 1}, /* 100 */ |
508 | {"XMODEM", models+15, 1}, /* 101 */ |
509 | {"ZMODEM", models+15, 0}, /* 102 */ |
510 | {NULL, NULL, 0}, /* terminating entry */ |
511 | }; |
512 | # define NALIASES 103 |
513 | |
514 | # endif /* BMP_BIT */ |
515 | #else /* PRESETS */ |
516 | |
517 | static const struct mpreset models[] = { |
518 | { 0UL, 0, 0, P_BE, 0, 0, NULL }, /* terminating entry */ |
519 | }; |
520 | # define NPRESETS 0 |
521 | |
522 | static const struct malias aliases[] = { |
523 | {NULL, NULL, 0}, /* terminating entry */ |
524 | }; |
525 | # define NALIASES 0 |
526 | |
527 | #endif /* PRESETS */ |
528 | |
529 | static const poly_t pzero = PZERO; |
530 | |
531 | static int acmp(const struct malias *, const struct malias *); |
532 | static void munpack(model_t *, const struct mpreset *); |
533 | |
534 | /* copy a parameter of a preset into a model */ |
535 | #define MUNPACK(parm) \ |
536 | praloc(&dest->parm, (src->b##parm ? src->width : 0UL)); \ |
537 | for(iter=0UL, idx=0UL; iter < dest->parm.length; iter += BMP_BIT, ++idx)\ |
538 | dest->parm.bitmap[idx] = src->b##parm[idx]; |
539 | |
540 | /* Definitions */ |
541 | |
542 | void |
543 | mcpy(model_t *dest, const model_t *src) { |
544 | /* Copies the parameters of src to dest. |
545 | * dest must be an initialised model. |
546 | */ |
547 | if(!dest || !src) return; |
548 | pcpy(&dest->spoly, src->spoly); |
549 | pcpy(&dest->init, src->init); |
550 | pcpy(&dest->xorout, src->xorout); |
551 | pcpy(&dest->check, src->check); |
552 | dest->flags = src->flags; |
553 | /* link to the name as it is static */ |
554 | dest->name = src->name; |
555 | } |
556 | |
557 | void |
558 | mfree(model_t *model) { |
559 | /* Frees the parameters of model. */ |
560 | if(!model) return; |
561 | pfree(&model->spoly); |
562 | pfree(&model->init); |
563 | pfree(&model->xorout); |
564 | pfree(&model->check); |
565 | /* not name as it is static */ |
566 | /* not model either, it might point to an array! */ |
567 | } |
568 | |
569 | int |
570 | mcmp(const model_t *a, const model_t *b) { |
571 | /* Compares a and b for identical effect, i.e. disregarding |
572 | * trailing zeroes in parameter polys. |
573 | * Intended for bsearch() to find a matching model in models[]. |
574 | */ |
575 | int result; |
576 | if(!a || !b) return(!b - !a); |
577 | if((result = psncmp(&a->spoly, &b->spoly))) return(result); |
578 | if((result = psncmp(&a->init, &b->init))) return(result); |
579 | if((a->flags & P_REFIN) && (~b->flags & P_REFIN)) return(1); |
580 | if((~a->flags & P_REFIN) && (b->flags & P_REFIN)) return(-1); |
581 | if((a->flags & P_REFOUT) && (~b->flags & P_REFOUT)) return(1); |
582 | if((~a->flags & P_REFOUT) && (b->flags & P_REFOUT)) return(-1); |
583 | return(psncmp(&a->xorout, &b->xorout)); |
584 | } |
585 | |
586 | int |
587 | mbynam(model_t *dest, const char *key) { |
588 | /* Sets parameters in dest according to the model named by key. |
589 | */ |
590 | struct malias akey = {NULL, NULL, 0}, *aptr; |
591 | char *ukey, *uptr; |
592 | |
593 | if(!aliases->name) |
594 | return(-1); |
595 | if(!(ukey = malloc((size_t) 1 + strlen(key)))) |
596 | uerror("cannot allocate memory for comparison string"); |
597 | akey.name = uptr = ukey; |
598 | do |
599 | *uptr++ = toupper(*key); |
600 | while(*key++); |
601 | |
602 | aptr = bsearch(&akey, aliases, NALIASES, sizeof(struct malias), (int (*)(const void *, const void *)) &acmp); |
603 | free(ukey); |
604 | |
605 | if(aptr == NULL) |
606 | return(0); |
607 | munpack(dest, aptr->model); |
608 | return(1); |
609 | } |
610 | |
611 | void |
612 | mbynum(model_t *dest, int num) { |
613 | /* Sets parameters in dest according to the model indexed by num. */ |
614 | if(num > NPRESETS) |
615 | num = NPRESETS; |
616 | munpack(dest, models+num); |
617 | } |
618 | |
619 | int |
620 | mcount(void) { |
621 | /* Returns the number of preset models. */ |
622 | return(NPRESETS); |
623 | } |
624 | |
625 | char * |
626 | mnames(void) { |
627 | /* Returns a malloc()-ed string of the names of all preset |
628 | * models, separated by newlines and terminated by NULL. |
629 | * Aliases are not listed. |
630 | */ |
631 | size_t size = 0; |
632 | char *string, *sptr; |
633 | const struct malias *aptr = aliases; |
634 | |
635 | while(aptr->name) { |
636 | if(aptr->isprimry) |
637 | size += strlen(aptr->name) + 1; |
638 | ++aptr; |
639 | } |
640 | if(!size) return(NULL); |
641 | if((string = malloc(size))) { |
642 | aptr = aliases; |
643 | sptr = string; |
644 | while(aptr->name) { |
645 | if(aptr->isprimry) { |
646 | strcpy(sptr, aptr->name); |
647 | sptr += strlen(aptr->name); |
648 | *sptr++ = '\n'; |
649 | } |
650 | ++aptr; |
651 | } |
652 | *--sptr = '\0'; |
653 | } else |
654 | uerror("cannot allocate memory for list of models"); |
655 | |
656 | return(string); |
657 | } |
658 | |
659 | char * |
660 | mtostr(const model_t *model) { |
661 | /* Returns a malloc()-ed string containing a Williams model |
662 | * record representing the input model. |
663 | * mcanon() should be called on the argument before printing. |
664 | */ |
665 | size_t size; |
666 | char *polystr, *initstr, *xorotstr, *checkstr, strbuf[512], *string = NULL; |
667 | |
668 | if(!model) return(NULL); |
669 | polystr = ptostr(model->spoly, P_RTJUST, 4); |
670 | initstr = ptostr(model->init, P_RTJUST, 4); |
671 | xorotstr = ptostr(model->xorout, P_RTJUST, 4); |
672 | checkstr = ptostr(model->check, P_RTJUST, 4); |
673 | |
674 | sprintf(strbuf, "%lu", plen(model->spoly)); |
675 | size = |
676 | 70 |
677 | + (model->name && *model->name ? 2 + strlen(model->name) : 6) |
678 | + strlen(strbuf) |
679 | + (polystr && *polystr ? strlen(polystr) : 6) |
680 | + (initstr && *initstr ? strlen(initstr) : 6) |
681 | + (model->flags & P_REFIN ? 4 : 5) |
682 | + (model->flags & P_REFOUT ? 4 : 5) |
683 | + (xorotstr && *xorotstr ? strlen(xorotstr) : 6) |
684 | + (checkstr && *checkstr ? strlen(checkstr) : 6); |
685 | if((string = malloc(size))) { |
686 | sprintf(strbuf, "\"%s\"", model->name); |
687 | sprintf(string, |
688 | "width=%lu " |
689 | "poly=0x%s " |
690 | "init=0x%s " |
691 | "refin=%s " |
692 | "refout=%s " |
693 | "xorout=0x%s " |
694 | "check=0x%s " |
695 | "name=%s", |
696 | plen(model->spoly), |
697 | polystr && *polystr ? polystr : "(none)", |
698 | initstr && *initstr ? initstr : "(none)", |
699 | (model->flags & P_REFIN) ? "true" : "false", |
700 | (model->flags & P_REFOUT) ? "true" : "false", |
701 | xorotstr && *xorotstr ? xorotstr : "(none)", |
702 | checkstr && *checkstr ? checkstr : "(none)", |
703 | (model->name && *model->name) ? strbuf : "(none)"); |
704 | } |
705 | free(polystr); |
706 | free(initstr); |
707 | free(xorotstr); |
708 | free(checkstr); |
709 | if(!string) |
710 | uerror("cannot allocate memory for model description"); |
711 | return(string); |
712 | } |
713 | |
714 | void |
715 | mmatch(model_t *model, int flags) { |
716 | /* searches models[] for a model matching the argument, and links a name if found |
717 | * if flags & M_OVERWR, copies the found model onto the argument. */ |
718 | model_t *mptr; |
719 | if(!model) return; |
720 | |
721 | mptr = bsearch(model, models, NPRESETS, sizeof(model_t), (int (*)(const void *, const void *)) &mcmp); |
722 | if(mptr) { |
723 | model->name = mptr->name; |
724 | if(flags & M_OVERWR) |
725 | mcpy(model, mptr); |
726 | } |
727 | } |
728 | |
729 | void |
730 | mcanon(model_t *model) { |
731 | /* canonicalise a model */ |
732 | unsigned long dlen; |
733 | |
734 | if(!model) return; |
735 | |
736 | /* extending on the right here. This preserves the functionality |
737 | * of a presumed working model. |
738 | */ |
739 | psnorm(&model->spoly); |
740 | dlen = plen(model->spoly); |
741 | praloc(&model->init, dlen); |
742 | praloc(&model->xorout, dlen); |
743 | |
744 | if(!plen(model->check)) |
745 | mcheck(model); |
746 | } |
747 | |
748 | void |
749 | mcheck(model_t *model) { |
750 | /* calculate a check for the model */ |
751 | poly_t checkstr, check; |
752 | |
753 | /* generate the check string with the correct bit order */ |
754 | checkstr = strtop("313233343536373839", model->flags, 8); |
755 | check = pcrc(checkstr, model->spoly, model->init, pzero, model->flags); |
756 | if(model->flags & P_REFOUT) |
757 | prev(&check); |
758 | psum(&check, model->xorout, 0UL); |
759 | model->check = check; |
760 | pfree(&checkstr); |
761 | } |
762 | |
763 | void |
764 | mrev(model_t *model) { |
765 | /* reverse the model to calculate reversed CRCs */ |
766 | /* Here we invert RefIn and RefOut so that the user need only |
767 | * reverse the order of characters in the arguments, not the |
768 | * characters themselves. If RefOut=True, the mirror image of |
769 | * Init seen through RefOut becomes XorOut, and as RefOut |
770 | * becomes false, the XorOut value moved to Init stays upright. |
771 | * If RefOut=False, Init transfers to XorOut without reflection |
772 | * but the new Init must be reflected to present the same image, |
773 | * as RefOut becomes true. |
774 | */ |
775 | poly_t temp; |
776 | |
777 | prcp(&model->spoly); |
778 | if(model->flags & P_REFOUT) |
779 | prev(&model->init); |
780 | else |
781 | prev(&model->xorout); |
782 | |
783 | /* exchange init and xorout */ |
784 | temp = model->init; |
785 | model->init = model->xorout; |
786 | model->xorout = temp; |
787 | |
788 | /* invert refin and refout */ |
789 | model->flags ^= P_REFIN | P_REFOUT; |
790 | |
791 | mnovel(model); |
792 | } |
793 | |
794 | void |
795 | mnovel(model_t *model) { |
796 | /* remove name and check string from modified model */ |
797 | model->name = NULL; |
798 | pfree(&model->check); |
799 | } |
800 | |
801 | static int |
802 | acmp(const struct malias *a, const struct malias *b) { |
803 | /* compares two aliases, for use in bsearch */ |
804 | if(!a || !b) return(!b - !a); |
805 | if(!a->name || !b->name) return(!b->name - !a->name); |
806 | return(strcmp(a->name, b->name)); |
807 | } |
808 | |
809 | static void |
810 | munpack(model_t *dest, const struct mpreset *src) { |
811 | /* Copies the parameters of src to dest. |
812 | * dest must be an initialised model. |
813 | */ |
814 | unsigned long iter, idx; |
815 | if(!dest || !src) return; |
816 | MUNPACK(spoly); |
817 | MUNPACK(init); |
818 | MUNPACK(xorout); |
819 | MUNPACK(check); |
820 | dest->flags = src->flags; |
821 | /* link to the name as it is static */ |
822 | dest->name = src->name; |
823 | } |