]>
Commit | Line | Data |
---|---|---|
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 |