]>
Commit | Line | Data |
---|---|---|
5ff3c401 | 1 | --[[ |
2 | This is an experimental lib. | |
3 | --]] | |
4 | local utils = require('utils') | |
5 | ||
6 | -- LOOKUP Tables | |
7 | local perm = {} | |
8 | perm [1]= { 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5, 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA } | |
9 | perm [2]= { 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4, 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB } | |
10 | perm [3]= { 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7, 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8 } | |
11 | perm [4]= { 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6, 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9 } | |
12 | perm [5]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE } | |
13 | perm [6]= { 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0, 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF } | |
14 | perm [7]= { 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3, 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC } | |
15 | perm [8]= { 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2, 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD } | |
16 | perm [9]= { 0x8, 0x9, 0xB, 0xA, 0xF, 0xE, 0xC, 0xD, 0x7, 0x6, 0x4, 0x5, 0x0, 0x1, 0x3, 0x2 } | |
17 | perm [10]= { 0x9, 0x8, 0xA, 0xB, 0xE, 0xF, 0xD, 0xC, 0x6, 0x7, 0x5, 0x4, 0x1, 0x0, 0x2, 0x3 } | |
18 | perm [11]= { 0xA, 0xB, 0x9, 0x8, 0xD, 0xC, 0xE, 0xF, 0x5, 0x4, 0x6, 0x7, 0x2, 0x3, 0x1, 0x0 } | |
19 | perm [12]= { 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE, 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1 } | |
20 | perm [13]= { 0xC, 0xD, 0xF, 0xE, 0xB, 0xA, 0x8, 0x9, 0x3, 0x2, 0x0, 0x1, 0x4, 0x5, 0x7, 0x6 } | |
21 | perm [14]= { 0xD, 0xC, 0xE, 0xF, 0xA, 0xB, 0x9, 0x8, 0x2, 0x3, 0x1, 0x0, 0x5, 0x4, 0x6, 0x7 } | |
22 | perm [15]= { 0xE, 0xF, 0xD, 0xC, 0x9, 0x8, 0xA, 0xB, 0x1, 0x0, 0x2, 0x3, 0x6, 0x7, 0x5, 0x4 } | |
23 | perm [16]= { 0xF, 0xE, 0xC, 0xD, 0x8, 0x9, 0xB, 0xA, 0x0, 0x1, 0x3, 0x2, 0x7, 0x6, 0x4, 0x5 } | |
24 | ||
25 | local shifts = {} | |
26 | shifts[1]= { 0x4, 0x5, 0x7, 0x6, 0x3, 0x2, 0x0, 0x1, 0xB, 0xA, 0x8, 0x9, 0xC, 0xD, 0xF, 0xE } | |
27 | shifts[2]= { 0x4, 0xB, 0xB, 0x4, 0xB, 0x4, 0x4, 0xB, 0xA, 0x5, 0x5, 0xA, 0x5, 0xA, 0xA, 0x5 } | |
28 | shifts[3]= { 0xB, 0x6, 0x0, 0xD, 0xD, 0x0, 0x6, 0xB, 0x6, 0xB, 0xD, 0x0, 0x0, 0xD, 0xB, 0x6 } | |
29 | shifts[4]= { 0xE, 0x5, 0x9, 0x2, 0x0, 0xB, 0x7, 0xC, 0x3, 0x8, 0x4, 0xF, 0xD, 0x6, 0xA, 0x1 } | |
30 | shifts[5]= { 0x4, 0xE, 0x1, 0xB, 0xF, 0x5, 0xA, 0x0, 0x3, 0x9, 0x6, 0xC, 0x8, 0x2, 0xD, 0x7 } | |
31 | shifts[6]= { 0xA, 0x4, 0x7, 0x9, 0x0, 0xE, 0xD, 0x3, 0xE, 0x0, 0x3, 0xD, 0x4, 0xA, 0x9, 0x7 } | |
32 | shifts[7]= { 0xE, 0x6, 0xE, 0x6, 0xF, 0x7, 0xF, 0x7, 0xD, 0x5, 0xD, 0x5, 0xC, 0x4, 0xC, 0x4 } | |
33 | shifts[8]= { 0x7, 0x1, 0xB, 0xD, 0xE, 0x8, 0x2, 0x4, 0x4, 0x2, 0x8, 0xE, 0xD, 0xB, 0x1, 0x7 } | |
34 | shifts[9]= { 0xD, 0xB, 0x0, 0x6, 0x6, 0x0, 0xB, 0xD, 0xA, 0xC, 0x7, 0x1, 0x1, 0x7, 0xC, 0xA } | |
35 | shifts[10]= { 0xe, 0x1, 0x1, 0xe, 0x1, 0xe, 0xe, 0x1, 0x1, 0xe, 0xe, 0x1, 0xe, 0x1, 0x1, 0xe } | |
36 | ||
37 | local function ApplyPermutationAndShifts( pos, value, nibble) | |
38 | local el2bytes = shifts[pos] | |
39 | local el2 = el2bytes[nibble+1] --one indexed | |
40 | local shiftInit = el2bytes[1] | |
41 | local permrow = perm[shiftInit+1] | |
42 | local j = 1 | |
43 | for i = 1,16 do | |
44 | if permrow[i] == el2 then | |
45 | j = i | |
46 | break | |
47 | end | |
48 | end | |
49 | local rsbytes = perm[value+1] | |
50 | local rs = rsbytes[j] | |
51 | return rs | |
52 | end | |
53 | ||
54 | local function GetOne( uid, block ) | |
55 | ||
56 | if uid == nil then return nil, 'empty uid string' end | |
57 | if #uid == 0 then return nil, 'empty uid string' end | |
58 | if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end | |
59 | if type(block) ~= 'number' then return nil, 'block is not number' end | |
60 | if block > 16 or block < 0 then return nil, 'block is out-of-range' end | |
61 | ||
62 | local s = ('%s%02X'):format(uid,block) | |
63 | local nibble1 = tonumber(s:sub(1,1),16) + 1 | |
64 | ||
65 | local permuted = '' | |
66 | for i = 1, #s do | |
67 | local el_row = shifts[i] | |
68 | local el_value = el_row[nibble1] | |
69 | j = 1 | |
70 | while j <= i do | |
71 | if i-j > 0 then | |
72 | local nibble = tonumber(s:sub(j+1,j+1),16) | |
73 | el_value = ApplyPermutationAndShifts(i-j, el_value, nibble) | |
74 | end | |
75 | j = j+1 | |
76 | end | |
77 | permuted =('%s%X'):format(permuted,el_value) | |
78 | end | |
79 | ||
80 | permuted = 'C2'..permuted | |
81 | local crc64numStr = utils.Crc64(permuted) | |
82 | local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true) | |
83 | local key = utils.ConvertBytesToHex(keybytes) | |
84 | return key:sub(1,12) | |
85 | end | |
86 | ||
87 | local PreCalc = | |
88 | { | |
89 | GetAll = function(id) | |
90 | if id == nil then return nil, 'empty string' end | |
91 | if #id == 0 then return nil, 'empty string' end | |
92 | if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end | |
93 | ||
94 | local list = '4b0b20107ccb' | |
95 | for i = 1,15 do | |
96 | local key, err = GetOne(id,i) | |
97 | if not key then return oops(err) end | |
98 | list = list..key | |
99 | end | |
100 | return list | |
101 | end, | |
102 | } | |
103 | return PreCalc |