9ccfb3a8 |
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 shiftbytes = shifts[pos] |
39 | local shiftElem = shiftbytes[nibble+1] --one indexed |
40 | local shiftOne = shiftbytes[1] |
41 | local rs = bit32.bxor(value, bit32.bxor(shiftOne, shiftElem)) |
42 | return rs |
43 | end |
44 | |
45 | local function GetOne( uid, block ) |
46 | |
47 | if uid == nil then return nil, 'empty uid string' end |
48 | if #uid == 0 then return nil, 'empty uid string' end |
49 | if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end |
50 | if type(block) ~= 'number' then return nil, 'block is not number' end |
51 | if block > 16 or block < 0 then return nil, 'block is out-of-range' end |
52 | |
53 | local s = ('%s%02X'):format(uid,block) |
54 | local nibble1 = tonumber(s:sub(1,1),16) + 1 |
55 | |
56 | local permuted = '' |
57 | for i = 1, #s do |
58 | local el_row = shifts[i] |
59 | local el_value = el_row[nibble1] |
60 | j = 1 |
61 | while j <= i do |
62 | if i-j > 0 then |
63 | local nibble = tonumber(s:sub(j+1,j+1),16) |
64 | el_value = ApplyPermutationAndShifts(i-j, el_value, nibble) |
65 | end |
66 | j = j+1 |
67 | end |
68 | permuted =('%s%X'):format(permuted,el_value) |
69 | end |
70 | |
71 | permuted = 'C2'..permuted |
72 | local crc64numStr = utils.Crc64(permuted) |
73 | local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true) |
74 | local key = utils.ConvertBytesToHex(keybytes) |
75 | return key:sub(1,12) |
76 | end |
77 | |
78 | local PreCalc = |
79 | { |
80 | GetAll = function(id) |
81 | if id == nil then return nil, 'empty string' end |
82 | if #id == 0 then return nil, 'empty string' end |
83 | if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end |
84 | |
85 | local list = '4b0b20107ccb' |
86 | for i = 1,15 do |
87 | local key, err = GetOne(id,i) |
88 | if not key then return oops(err) end |
89 | list = list..key |
90 | end |
91 | return list |
92 | end, |
93 | } |
94 | return PreCalc |