Renamed FFLuCI to LuCI, ffluci to luci and Freifunk Lua Configuration Interface to...
[project/luci.git] / core / src / 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("luci.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