1 local cmds
= require('commands')
2 local getopt
= require('getopt')
3 local utils
= require('utils')
4 local json
= require('dkjson')
5 local ac
= require('ansicolors')
8 author
= "Christian Herrmann"
11 This script loads a json format file, with the field "data" and a hexbyte array of data. Ie t55x7 dump,
12 it tries to identify which system based on block1, and detect block0 settings.
13 The script returns a file with the new identification added, in json format. The output is save in 'dumpdata.json'
16 script run lf_ident_json -i lf_t55xx.json
19 script run lf_en4100_bulk.lua [-h] [-c] [-p password] [-s <start cn>] [-v]
23 -i : infile ( .json format )
30 string.startswith
= function(self
, str
)
31 return self
:find('^' .. str
) ~= nil
35 -- A debug printout-function
36 local function dbg(args
)
37 if not DEBUG
then return end
38 if type(args
) == 'table' then
49 -- This is only meant to be used when errors occur
50 local function oops(err
)
52 core
.clearCommandBuffer()
62 print(ac
.cyan
..'Usage'..ac
.reset
)
64 print(ac
.cyan
..'Arguments'..ac
.reset
)
66 print(ac
.cyan
..'Example usage'..ac
.reset
)
71 local function exitMsg(msg
)
72 print( string.rep('--',20) )
73 print( string.rep('--',20) )
78 --- loads a json formatted text file with
80 -- @param input the file containing the json-dump (defaults to dumpdata.json)
81 local function load_json(input
)
82 input
= input
or 'dumpdata.json'
83 local infile
= io
.open(input
, "rb")
84 if not infile
then return oops(string.format("Could not read file %s", tostring(input
))) end
87 local t
= infile
:read("*all")
90 local obj
, pos
, err
= json
.decode(t
, 1, nil)
91 if err
then return oops(string.format("importing json file failed. %s", err
)) end
93 print(string.format('loaded file %s', input
))
98 local function save_json(data
, filename
)
99 filename
= filename
or 'dumpdata.json'
100 local outfile
= io
.open(filename
, "w")
101 if not outfile
then return oops(string.format("Could not write to file %s", tostring(filename
))) end
107 local function encode(blocks
)
108 return json
.encode (blocks
, { indent
= true })
112 local function getDefault(block0
)
114 block0
= block0
:upper()
116 local T55X7_DEFAULT_CONFIG_BLOCK
= '000880E8' --// compat mode, RF/32, manchester, STT, 7 data blocks
117 local T55X7_RAW_CONFIG_BLOCK
= '000880E0' --// compat mode, RF/32, manchester, 7 data blocks
118 local T55X7_EM_UNIQUE_CONFIG_BLOCK
= '00148040' --// emulate em4x02/unique - compat mode, manchester, RF/64, 2 data blocks
119 -- FDXB requires data inversion and BiPhase 57 is simply BipHase 50 inverted, so we can either do it using the modulation scheme or the inversion flag
120 -- we've done both below to prove that it works either way, and the modulation value for BiPhase 50 in the Atmel data sheet of binary "10001" (17) is a typo,
121 -- and it should actually be "10000" (16)
122 --local T55X7_FDXB_CONFIG_BLOCK 903F8080 // emulate fdx-b - xtended mode, biPhase ('57), RF/32, 4 data blocks
123 local T55X7_FDXB_CONFIG_BLOCK
= '903F0082' --// emulate fdx-b - xtended mode, biPhase ('50), invert data, RF/32, 4 data blocks
124 local T55X7_HID_26_CONFIG_BLOCK
= '00107060' --// hid 26 bit - compat mode, FSK2a, RF/50, 3 data blocks
125 local T55X7_PYRAMID_CONFIG_BLOCK
= '00107080' --// Pyramid 26 bit - compat mode, FSK2a, RF/50, 4 data blocks
126 local T55X7_INDALA_64_CONFIG_BLOCK
= '00081040' --// emulate indala 64 bit - compat mode, PSK1, psk carrier FC * 2, RF/32, 2 data block
127 local T55X7_INDALA_224_CONFIG_BLOCK
= '000810E0' --// emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, RF/32, 7 data block
128 local T55X7_GUARDPROXII_CONFIG_BLOCK
= '00150060' --// Direct modulation, Biphase, RF/64, 3 data blocks
129 local T55X7_VIKING_CONFIG_BLOCK
= '00088040' --// compat mode, manchester, RF/32, 2 data blocks
130 local T55X7_NORALYS_CONFIG_BLOCK
= '00088C6A' --// NORALYS (KCP3000) -- compat mode, manchester, inverse, RF/32, STT, 3 data blocks
131 local T55X7_IOPROX_CONFIG_BLOCK
= '00147040' --// HID FSK2a, RF/64, 2 data blocks
132 local T55X7_PRESCO_CONFIG_BLOCK
= '00088088' --// manchester, RF/32, STT, 5 data blocks
133 local T5555_DEFAULT_CONFIG_BLOCK
= '6001F004' --// ask, manchester, RF/64, 2 data blocks?
134 local T55X7_STARPROX
= '00088C42' --// manchester, inverse, RF/32, 2 data blocks
135 local T55X7_VISA2K_CONFIG_BLOCK
= '00148068' --// VISA2000 - manchester, RF/64, STT, 3 data blocks
136 local T55X7_SECURAKEY_CONFIG_BLOCK
= 'F00C8060' --// Securakey - manchester, RF/40, 3 data blocks
137 local T55X7_ST
= 'F0088058' --// manchester, RF/32, STT, pwd, 2 data blocks
140 if block0
== T55X7_DEFAULT_CONFIG_BLOCK
then return 'T55X7_DEFAULT_CONFIG_BLOCK :: compat mode, manchester, RF/32, STT, 7 data blocks'
141 elseif block0
== T55X7_RAW_CONFIG_BLOCK
then return 'T55X7_RAW_CONFIG_BLOCK :: compat mode, manchester, RF/32, 7 data blocks'
142 elseif block0
== T55X7_EM_UNIQUE_CONFIG_BLOCK
then return 'T55X7_EM_UNIQUE_CONFIG_BLOCK :: emulate em4x02/unique - compat mode, manchester, RF/64, 2 data blocks'
143 elseif block0
== T55X7_FDXB_CONFIG_BLOCK
then return 'T55X7_FDXB_CONFIG_BLOCK :: emulate fdx-b - xtended mode, BiPhase (50, invert data, RF/32, 4 data blocks'
144 elseif block0
== T55X7_PYRAMID_CONFIG_BLOCK
then return 'T55X7_PYRAMID_CONFIG_BLOCK :: Pyramid 26 bit - compat mode, FSK2a, RF/50, 4 data blocks'
145 elseif block0
== T55X7_HID_26_CONFIG_BLOCK
then return 'T55X7_HID_26_CONFIG_BLOCK :: hid 26 bit - compat mode, FSK2a, RF/50, 3 data blocks'
146 elseif block0
== T55X7_INDALA_64_CONFIG_BLOCK
then return 'T55X7_INDALA_64_CONFIG_BLOCK :: emulate indala 64 bit - compat mode, PSK1, psk carrier FC * 2, RF/32, 2 data blocks'
147 elseif block0
== T55X7_INDALA_224_CONFIG_BLOCK
then return 'T55X7_INDALA_224_CONFIG_BLOCK :: emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, RF/32, 7 data blocks'
148 elseif block0
== T55X7_GUARDPROXII_CONFIG_BLOCK
then return 'T55X7_GUARDPROXII_CONFIG_BLOCK :: biphase, direct modulation, RF/64, 3 data blocks'
149 elseif block0
== T55X7_VIKING_CONFIG_BLOCK
then return 'T55X7_VIKING_CONFIG_BLOCK :: compat mode, manchester, RF/32, 2 data blocks'
150 elseif block0
== T55X7_NORALYS_CONFIG_BLOCK
then return 'T55X7_NORALYS_CONFIG_BLOCK :: NORALYS (KCP3000) -- compat mode, manchester, inverse, RF/32, STT, 3 data blocks'
151 elseif block0
== T55X7_IOPROX_CONFIG_BLOCK
then return 'T55X7_IOPROX_CONFIG_BLOCK :: HID FSK2a, RF/64, 2 data blocks'
152 elseif block0
== T55X7_PRESCO_CONFIG_BLOCK
then return 'T55X7_PRESCO_CONFIG_BLOCK :: manchester, RF/32, STT, 5 data blocks'
153 elseif block0
== T5555_DEFAULT_CONFIG_BLOCK
then return 'T5555_DEFAULT_CONFIG_BLOCK :: ask, manchester, RF/64, 2 data blocks?'
154 elseif block0
== T55X7_STARPROX
then return 'T55X7_STARPROX :: manchester, inverse, RF/32, 2 data blocks'
155 elseif block0
== T55X7_VISA2K_CONFIG_BLOCK
then return 'T55X7_VISA2K_CONFIG_BLOCK :: manchester, RF/64, STT, 3 data blocks'
156 elseif block0
== T55X7_SECURAKEY_CONFIG_BLOCK
then return 'T55X7_SECURAKEY_CONFIG_BLOCK :: manchester, RF/40, 3 data blocks'
157 else return 'unknown configblock'..' '..block0
162 -- map first block0 with name
163 local function getConfigBlock(block
)
165 block
= block
:lower()
168 if block
:startswith("f20000") then
169 return '00088C42', 'Card is a Viking / Starprox'
171 if block
:startswith('9522') then
172 return '00088048', 'Card is an unknown badge'
174 if block
:startswith('56495332') then
175 return '00148068', 'Card is VISA2000'
177 if block
:startswith('1d555955') then
178 return '00107060', 'Card is HID Prox, (Prastel MTAG, sold by ABMatic)'
180 if block
:startswith('bb0214ff') or block
:startswith('bb0314ff') then
181 return '00088C6A', 'Card is Noralsy Blue, KCP3000'
183 --#If the block starts with ff8/9/a/b/c
184 if block
:find('^(ff[8-9a-c])') then
185 dbg('#This is a regular EM 410 tag, using a FF pattern (from FF8 to FFF)')
186 dbg('#Covering from tag 1 to tag id 9FFFFFFFFF')
187 return '00148040', 'Old rectangular Noralsy'
189 if block
:startswith('011db') then
190 return '00107060', 'Card is AWID'
192 if block
:startswith('f98c7038') then
193 return '00150060', 'Card is Guard All/ verex'
195 if block
:startswith('ffff0000') then
196 return '00158040', 'Card is Jablotron'
198 if block
:startswith('10d00000') then
199 return '00088088', 'Card is Presco'
201 if block
:startswith('00010101') then
202 return '00107080', 'Card is Pyramid'
205 return result
, 'unknown tag'
209 -- The main entry point
212 print( string.rep('--',20) )
213 print( string.rep('--',20) )
216 if #args
== 0 then return help() end
221 -- Read the parameters
222 for o
, a
in getopt
.getopt(args
, 'hi:') do
223 if o
== "h" then return help() end
224 if o
== "i" then lines
= load_json(a
) end
227 --for i = 1, #data do
228 for _
,i
in pairs(lines
) do
232 for ix
= 1, #i
.data
, 8 do
233 one
['blk_'..index
] = i
.data
:sub(ix
,ix
+7)
237 local mconf
, msg
= getConfigBlock(one
["blk_1"])
238 one
["identification"] = msg
239 one
["config_desc"] = getDefault(one
["blk_0"])
241 if msg
:find('badge') then
244 table.insert(out
, one
)
246 save_json( encode(out
) , nil)