* Fixed ffluci.util.trim, ffluci.util.split
[project/luci.git] / core / src / ffluci / bits.lua
1 --[[
2 /*
3 * Copyright (c) 2007 Tim Kelly/Dialectronics
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to permit
10 * persons to whom the Software is furnished to do so, subject to the
11 * following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21 * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 --]]
26
27 --[[
28 /*
29 * Copyright (c) 2007 Tim Kelly/Dialectronics
30 *
31 * Permission is hereby granted, free of charge, to any person obtaining
32 * a copy of this software and associated documentation files (the
33 * "Software"), to deal in the Software without restriction, including
34 * without limitation the rights to use, copy, modify, merge, publish,
35 * distribute, sublicense, and/or sell copies of the Software, and to permit
36 * persons to whom the Software is furnished to do so, subject to the
37 * following conditions:
38 *
39 * The above copyright notice and this permission notice shall be
40 * included in all copies or substantial portions of the Software.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
43 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
47 * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
48 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49 */
50
51 --]]
52
53 module("ffluci.bits", package.seeall);
54
55 local hex2bin = {
56 ["0"] = "0000",
57 ["1"] = "0001",
58 ["2"] = "0010",
59 ["3"] = "0011",
60 ["4"] = "0100",
61 ["5"] = "0101",
62 ["6"] = "0110",
63 ["7"] = "0111",
64 ["8"] = "1000",
65 ["9"] = "1001",
66 ["a"] = "1010",
67 ["b"] = "1011",
68 ["c"] = "1100",
69 ["d"] = "1101",
70 ["e"] = "1110",
71 ["f"] = "1111"
72 }
73
74
75
76 local bin2hex = {
77 ["0000"] = "0",
78 ["0001"] = "1",
79 ["0010"] = "2",
80 ["0011"] = "3",
81 ["0100"] = "4",
82 ["0101"] = "5",
83 ["0110"] = "6",
84 ["0111"] = "7",
85 ["1000"] = "8",
86 ["1001"] = "9",
87 ["1010"] = "A",
88 ["1011"] = "B",
89 ["1100"] = "C",
90 ["1101"] = "D",
91 ["1110"] = "E",
92 ["1111"] = "F"
93 }
94
95 --[[
96 local dec2hex = {
97 ["0"] = "0",
98 ["1"] = "1",
99 ["2"] = "2",
100 ["3"] = "3",
101 ["4"] = "4",
102 ["5"] = "5",
103 ["6"] = "6",
104 ["7"] = "7",
105 ["8"] = "8",
106 ["9"] = "9",
107 ["10"] = "A",
108 ["11"] = "B",
109 ["12"] = "C",
110 ["13"] = "D",
111 ["14"] = "E",
112 ["15"] = "F"
113 }
114 --]]
115
116
117 -- These functions are big-endian and take up to 32 bits
118
119 -- Hex2Bin
120 -- Bin2Hex
121 -- Hex2Dec
122 -- Dec2Hex
123 -- Bin2Dec
124 -- Dec2Bin
125
126
127 function Hex2Bin(s)
128
129 -- s -> hexadecimal string
130
131 local ret = ""
132 local i = 0
133
134
135 for i in string.gfind(s, ".") do
136 i = string.lower(i)
137
138 ret = ret..hex2bin[i]
139
140 end
141
142 return ret
143 end
144
145
146 function Bin2Hex(s)
147
148 -- s -> binary string
149
150 local l = 0
151 local h = ""
152 local b = ""
153 local rem
154
155 l = string.len(s)
156 rem = l % 4
157 l = l-1
158 h = ""
159
160 -- need to prepend zeros to eliminate mod 4
161 if (rem > 0) then
162 s = string.rep("0", 4 - rem)..s
163 end
164
165 for i = 1, l, 4 do
166 b = string.sub(s, i, i+3)
167 h = h..bin2hex[b]
168 end
169
170 return h
171
172 end
173
174
175 function Bin2Dec(s)
176
177 -- s -> binary string
178
179 local num = 0
180 local ex = string.len(s) - 1
181 local l = 0
182
183 l = ex + 1
184 for i = 1, l do
185 b = string.sub(s, i, i)
186 if b == "1" then
187 num = num + 2^ex
188 end
189 ex = ex - 1
190 end
191
192 return string.format("%u", num)
193
194 end
195
196
197
198 function Dec2Bin(s, num)
199
200 -- s -> Base10 string
201 -- num -> string length to extend to
202
203 local n
204
205 if (num == nil) then
206 n = 0
207 else
208 n = num
209 end
210
211 s = string.format("%x", s)
212
213 s = Hex2Bin(s)
214
215 while string.len(s) < n do
216 s = "0"..s
217 end
218
219 return s
220
221 end
222
223
224
225
226 function Hex2Dec(s)
227
228 -- s -> hexadecimal string
229
230 local s = Hex2Bin(s)
231
232 return Bin2Dec(s)
233
234 end
235
236
237
238 function Dec2Hex(s)
239
240 -- s -> Base10 string
241
242 s = string.format("%x", s)
243
244 return s
245
246 end
247
248
249
250
251 -- These functions are big-endian and will extend to 32 bits
252
253 -- BMAnd
254 -- BMNAnd
255 -- BMOr
256 -- BMXOr
257 -- BMNot
258
259
260 function BMAnd(v, m)
261
262 -- v -> hex string to be masked
263 -- m -> hex string mask
264
265 -- s -> hex string as masked
266
267 -- bv -> binary string of v
268 -- bm -> binary string mask
269
270 local bv = Hex2Bin(v)
271 local bm = Hex2Bin(m)
272
273 local i = 0
274 local s = ""
275
276 while (string.len(bv) < 32) do
277 bv = "0000"..bv
278 end
279
280 while (string.len(bm) < 32) do
281 bm = "0000"..bm
282 end
283
284
285 for i = 1, 32 do
286 cv = string.sub(bv, i, i)
287 cm = string.sub(bm, i, i)
288 if cv == cm then
289 if cv == "1" then
290 s = s.."1"
291 else
292 s = s.."0"
293 end
294 else
295 s = s.."0"
296
297 end
298 end
299
300 return Bin2Hex(s)
301
302 end
303
304
305 function BMNAnd(v, m)
306
307 -- v -> hex string to be masked
308 -- m -> hex string mask
309
310 -- s -> hex string as masked
311
312 -- bv -> binary string of v
313 -- bm -> binary string mask
314
315 local bv = Hex2Bin(v)
316 local bm = Hex2Bin(m)
317
318 local i = 0
319 local s = ""
320
321 while (string.len(bv) < 32) do
322 bv = "0000"..bv
323 end
324
325 while (string.len(bm) < 32) do
326 bm = "0000"..bm
327 end
328
329
330 for i = 1, 32 do
331 cv = string.sub(bv, i, i)
332 cm = string.sub(bm, i, i)
333 if cv == cm then
334 if cv == "1" then
335 s = s.."0"
336 else
337 s = s.."1"
338 end
339 else
340 s = s.."1"
341
342 end
343 end
344
345 return Bin2Hex(s)
346
347 end
348
349
350
351 function BMOr(v, m)
352
353 -- v -> hex string to be masked
354 -- m -> hex string mask
355
356 -- s -> hex string as masked
357
358 -- bv -> binary string of v
359 -- bm -> binary string mask
360
361 local bv = Hex2Bin(v)
362 local bm = Hex2Bin(m)
363
364 local i = 0
365 local s = ""
366
367 while (string.len(bv) < 32) do
368 bv = "0000"..bv
369 end
370
371 while (string.len(bm) < 32) do
372 bm = "0000"..bm
373 end
374
375
376 for i = 1, 32 do
377 cv = string.sub(bv, i, i)
378 cm = string.sub(bm, i, i)
379 if cv == "1" then
380 s = s.."1"
381 elseif cm == "1" then
382 s = s.."1"
383 else
384 s = s.."0"
385 end
386 end
387
388 return Bin2Hex(s)
389
390 end
391
392 function BMXOr(v, m)
393
394 -- v -> hex string to be masked
395 -- m -> hex string mask
396
397 -- s -> hex string as masked
398
399 -- bv -> binary string of v
400 -- bm -> binary string mask
401
402 local bv = Hex2Bin(v)
403 local bm = Hex2Bin(m)
404
405 local i = 0
406 local s = ""
407
408 while (string.len(bv) < 32) do
409 bv = "0000"..bv
410 end
411
412 while (string.len(bm) < 32) do
413 bm = "0000"..bm
414 end
415
416
417 for i = 1, 32 do
418 cv = string.sub(bv, i, i)
419 cm = string.sub(bm, i, i)
420 if cv == "1" then
421 if cm == "0" then
422 s = s.."1"
423 else
424 s = s.."0"
425 end
426 elseif cm == "1" then
427 if cv == "0" then
428 s = s.."1"
429 else
430 s = s.."0"
431 end
432 else
433 -- cv and cm == "0"
434 s = s.."0"
435 end
436 end
437
438 return Bin2Hex(s)
439
440 end
441
442
443 function BMNot(v, m)
444
445 -- v -> hex string to be masked
446 -- m -> hex string mask
447
448 -- s -> hex string as masked
449
450 -- bv -> binary string of v
451 -- bm -> binary string mask
452
453 local bv = Hex2Bin(v)
454 local bm = Hex2Bin(m)
455
456 local i = 0
457 local s = ""
458
459 while (string.len(bv) < 32) do
460 bv = "0000"..bv
461 end
462
463 while (string.len(bm) < 32) do
464 bm = "0000"..bm
465 end
466
467
468 for i = 1, 32 do
469 cv = string.sub(bv, i, i)
470 cm = string.sub(bm, i, i)
471 if cm == "1" then
472 if cv == "1" then
473 -- turn off
474 s = s.."0"
475 else
476 -- turn on
477 s = s.."1"
478 end
479 else
480 -- leave untouched
481 s = s..cv
482
483 end
484 end
485
486 return Bin2Hex(s)
487
488 end
489
490
491 -- these functions shift right and left, adding zeros to lost or gained bits
492 -- returned values are 32 bits long
493
494 -- BShRight(v, nb)
495 -- BShLeft(v, nb)
496
497
498 function BShRight(v, nb)
499
500 -- v -> hexstring value to be shifted
501 -- nb -> number of bits to shift to the right
502
503 -- s -> binary string of v
504
505 local s = Hex2Bin(v)
506
507 while (string.len(s) < 32) do
508 s = "0000"..s
509 end
510
511 s = string.sub(s, 1, 32 - nb)
512
513 while (string.len(s) < 32) do
514 s = "0"..s
515 end
516
517 return Bin2Hex(s)
518
519 end
520
521 function BShLeft(v, nb)
522
523 -- v -> hexstring value to be shifted
524 -- nb -> number of bits to shift to the right
525
526 -- s -> binary string of v
527
528 local s = Hex2Bin(v)
529
530 while (string.len(s) < 32) do
531 s = "0000"..s
532 end
533
534 s = string.sub(s, nb + 1, 32)
535
536 while (string.len(s) < 32) do
537 s = s.."0"
538 end
539
540 return Bin2Hex(s)
541
542 end