mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
lua: more fix mix of spaces & tabs
This commit is contained in:
parent
05ff45e550
commit
2d1a077ae4
14 changed files with 1423 additions and 1423 deletions
|
@ -1,78 +1,78 @@
|
||||||
--[[
|
--[[
|
||||||
local _errorcodes = {
|
local _errorcodes = {
|
||||||
SW_NO_ERROR = 0x9000,
|
SW_NO_ERROR = 0x9000,
|
||||||
SW_BYTES_REMAINING_00 = 0x6100, -- Response bytes remaining
|
SW_BYTES_REMAINING_00 = 0x6100, -- Response bytes remaining
|
||||||
SW_WARNING_STATE_UNCHANGED = 0x6200, -- Warning, card state unchanged =
|
SW_WARNING_STATE_UNCHANGED = 0x6200, -- Warning, card state unchanged =
|
||||||
SW_WRONG_LENGTH = 0x6700, -- : Wrong length
|
SW_WRONG_LENGTH = 0x6700, -- : Wrong length
|
||||||
SW_WRONG_P1P2 = 0x6B00, -- : Incorrect parameters (P1,P2)
|
SW_WRONG_P1P2 = 0x6B00, -- : Incorrect parameters (P1,P2)
|
||||||
SW_CORRECT_LENGTH_00 = 0x6C00, -- : Correct Expected Length (Le)
|
SW_CORRECT_LENGTH_00 = 0x6C00, -- : Correct Expected Length (Le)
|
||||||
SW_INS_NOT_SUPPORTED = 0x6D00, -- : INS value not supported
|
SW_INS_NOT_SUPPORTED = 0x6D00, -- : INS value not supported
|
||||||
SW_CLA_NOT_SUPPORTED = 0x6E00, -- : CLA value not supported
|
SW_CLA_NOT_SUPPORTED = 0x6E00, -- : CLA value not supported
|
||||||
SW_UNKNOWN = 0x6F00, -- : No precise diagnosis
|
SW_UNKNOWN = 0x6F00, -- : No precise diagnosis
|
||||||
|
|
||||||
SW_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881, -- : Card does not support the operation on the specified logical channel
|
SW_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881, -- : Card does not support the operation on the specified logical channel
|
||||||
SW_SECURE_MESSAGING_NOT_SUPPORTED = 0x6882, -- : Card does not support secure messaging
|
SW_SECURE_MESSAGING_NOT_SUPPORTED = 0x6882, -- : Card does not support secure messaging
|
||||||
SW_LAST_COMMAND_EXPECTED = 0x6883, -- : Last command in chain expected
|
SW_LAST_COMMAND_EXPECTED = 0x6883, -- : Last command in chain expected
|
||||||
SW_COMMAND_CHAINING_NOT_SUPPORTED = 0x6884, -- : Command chaining not supported
|
SW_COMMAND_CHAINING_NOT_SUPPORTED = 0x6884, -- : Command chaining not supported
|
||||||
|
|
||||||
SW_SECURITY_STATUS_NOT_SATISFIED = 0x6982, -- : Security condition not satisfied
|
SW_SECURITY_STATUS_NOT_SATISFIED = 0x6982, -- : Security condition not satisfied
|
||||||
SW_FILE_INVALID = 0x6983, -- : File invalid
|
SW_FILE_INVALID = 0x6983, -- : File invalid
|
||||||
SW_DATA_INVALID = 0x6984, -- : Data invalid
|
SW_DATA_INVALID = 0x6984, -- : Data invalid
|
||||||
SW_CONDITIONS_NOT_SATISFIED = 0x6985, -- : Conditions of use not satisfied
|
SW_CONDITIONS_NOT_SATISFIED = 0x6985, -- : Conditions of use not satisfied
|
||||||
SW_COMMAND_NOT_ALLOWED = 0x6986, -- : Command not allowed (no current EF)
|
SW_COMMAND_NOT_ALLOWED = 0x6986, -- : Command not allowed (no current EF)
|
||||||
SW_APPLET_SELECT_FAILED = 0x6999, -- : Applet selection failed
|
SW_APPLET_SELECT_FAILED = 0x6999, -- : Applet selection failed
|
||||||
|
|
||||||
SW_WRONG_DATA = 0x6A80, -- : Wrong data
|
SW_WRONG_DATA = 0x6A80, -- : Wrong data
|
||||||
SW_FUNC_NOT_SUPPORTED = 0x6A81, -- : Function not supported
|
SW_FUNC_NOT_SUPPORTED = 0x6A81, -- : Function not supported
|
||||||
SW_FILE_NOT_FOUND = 0x6A82, -- : File not found
|
SW_FILE_NOT_FOUND = 0x6A82, -- : File not found
|
||||||
SW_RECORD_NOT_FOUND = 0x6A83, -- : Record not found
|
SW_RECORD_NOT_FOUND = 0x6A83, -- : Record not found
|
||||||
SW_FILE_FULL = 0x6A84, -- : Not enough memory space in the file
|
SW_FILE_FULL = 0x6A84, -- : Not enough memory space in the file
|
||||||
SW_INCORRECT_P1P2 = 0x6A86, -- : Incorrect parameters (P1,P2)
|
SW_INCORRECT_P1P2 = 0x6A86, -- : Incorrect parameters (P1,P2)
|
||||||
}
|
}
|
||||||
--]]
|
--]]
|
||||||
local _errorcodes = {
|
local _errorcodes = {
|
||||||
SW_NO_ERROR = '9000',
|
SW_NO_ERROR = '9000',
|
||||||
SW_BYTES_REMAINING_00 = '6100', -- Response bytes remaining
|
SW_BYTES_REMAINING_00 = '6100', -- Response bytes remaining
|
||||||
SW_WARNING_STATE_UNCHANGED = '6200', -- Warning', card state unchanged =
|
SW_WARNING_STATE_UNCHANGED = '6200', -- Warning', card state unchanged =
|
||||||
SW_WRONG_LENGTH = '6700', -- : Wrong length
|
SW_WRONG_LENGTH = '6700', -- : Wrong length
|
||||||
SW_WRONG_P1P2 = '6B00', -- : Incorrect parameters (P1,P2)
|
SW_WRONG_P1P2 = '6B00', -- : Incorrect parameters (P1,P2)
|
||||||
SW_CORRECT_LENGTH_00 = '6C00', -- : Correct Expected Length (Le)
|
SW_CORRECT_LENGTH_00 = '6C00', -- : Correct Expected Length (Le)
|
||||||
SW_INS_NOT_SUPPORTED = '6D00', -- : INS value not supported
|
SW_INS_NOT_SUPPORTED = '6D00', -- : INS value not supported
|
||||||
SW_CLA_NOT_SUPPORTED = '6E00', -- : CLA value not supported
|
SW_CLA_NOT_SUPPORTED = '6E00', -- : CLA value not supported
|
||||||
SW_UNKNOWN = '6F00', -- : No precise diagnosis
|
SW_UNKNOWN = '6F00', -- : No precise diagnosis
|
||||||
|
|
||||||
SW_LOGICAL_CHANNEL_NOT_SUPPORTED = '6881', -- : Card does not support the operation on the specified logical channel
|
SW_LOGICAL_CHANNEL_NOT_SUPPORTED = '6881', -- : Card does not support the operation on the specified logical channel
|
||||||
SW_SECURE_MESSAGING_NOT_SUPPORTED = '6882', -- : Card does not support secure messaging
|
SW_SECURE_MESSAGING_NOT_SUPPORTED = '6882', -- : Card does not support secure messaging
|
||||||
SW_LAST_COMMAND_EXPECTED = '6883', -- : Last command in chain expected
|
SW_LAST_COMMAND_EXPECTED = '6883', -- : Last command in chain expected
|
||||||
SW_COMMAND_CHAINING_NOT_SUPPORTED = '6884', -- : Command chaining not supported
|
SW_COMMAND_CHAINING_NOT_SUPPORTED = '6884', -- : Command chaining not supported
|
||||||
|
|
||||||
SW_SECURITY_STATUS_NOT_SATISFIED = '6982', -- : Security condition not satisfied
|
SW_SECURITY_STATUS_NOT_SATISFIED = '6982', -- : Security condition not satisfied
|
||||||
SW_FILE_INVALID = '6983', -- : File invalid
|
SW_FILE_INVALID = '6983', -- : File invalid
|
||||||
SW_DATA_INVALID = '6984', -- : Data invalid
|
SW_DATA_INVALID = '6984', -- : Data invalid
|
||||||
SW_CONDITIONS_NOT_SATISFIED = '6985', -- : Conditions of use not satisfied
|
SW_CONDITIONS_NOT_SATISFIED = '6985', -- : Conditions of use not satisfied
|
||||||
SW_COMMAND_NOT_ALLOWED = '6986', -- : Command not allowed (no current EF)
|
SW_COMMAND_NOT_ALLOWED = '6986', -- : Command not allowed (no current EF)
|
||||||
SW_APPLET_SELECT_FAILED = '6999', -- : Applet selection failed
|
SW_APPLET_SELECT_FAILED = '6999', -- : Applet selection failed
|
||||||
|
|
||||||
SW_WRONG_DATA = '6A80', -- : Wrong data
|
SW_WRONG_DATA = '6A80', -- : Wrong data
|
||||||
SW_FUNC_NOT_SUPPORTED = '6A81', -- : Function not supported
|
SW_FUNC_NOT_SUPPORTED = '6A81', -- : Function not supported
|
||||||
SW_FILE_NOT_FOUND = '6A82', -- : File not found
|
SW_FILE_NOT_FOUND = '6A82', -- : File not found
|
||||||
SW_RECORD_NOT_FOUND = '6A83', -- : Record not found
|
SW_RECORD_NOT_FOUND = '6A83', -- : Record not found
|
||||||
SW_FILE_FULL = '6A84', -- : Not enough memory space in the file
|
SW_FILE_FULL = '6A84', -- : Not enough memory space in the file
|
||||||
SW_INCORRECT_P1P2 = '6A86', -- : Incorrect parameters (P1,P2)
|
SW_INCORRECT_P1P2 = '6A86', -- : Incorrect parameters (P1,P2)
|
||||||
}
|
}
|
||||||
|
|
||||||
local _reverse_lookup,k,v = {}
|
local _reverse_lookup,k,v = {}
|
||||||
for k, v in pairs(_errorcodes) do
|
for k, v in pairs(_errorcodes) do
|
||||||
_reverse_lookup[v] = k
|
_reverse_lookup[v] = k
|
||||||
end
|
end
|
||||||
|
|
||||||
_errorcodes.tostring = function(command)
|
_errorcodes.tostring = function(command)
|
||||||
if(type(command) == 'string') then
|
if(type(command) == 'string') then
|
||||||
return ("%s (%d)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command)
|
return ("%s (%d)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command)
|
||||||
end
|
end
|
||||||
if(type(command) == 'number') then
|
if(type(command) == 'number') then
|
||||||
return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command)
|
return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command)
|
||||||
end
|
end
|
||||||
return ("Error, numeric or string argument expected, got : %s"):format(tostring(command))
|
return ("Error, numeric or string argument expected, got : %s"):format(tostring(command))
|
||||||
end
|
end
|
||||||
return _errorcodes
|
return _errorcodes
|
|
@ -1,73 +1,73 @@
|
||||||
--[[
|
--[[
|
||||||
Handle Proxmark USB Commands
|
Handle Proxmark USB Commands
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
local _commands = require('usb_cmd')
|
local _commands = require('usb_cmd')
|
||||||
|
|
||||||
local _reverse_lookup,k,v = {}
|
local _reverse_lookup,k,v = {}
|
||||||
for k, v in pairs(_commands) do
|
for k, v in pairs(_commands) do
|
||||||
_reverse_lookup[v] = k
|
_reverse_lookup[v] = k
|
||||||
end
|
end
|
||||||
_commands.tostring = function(command)
|
_commands.tostring = function(command)
|
||||||
if(type(command) == 'number') then
|
if(type(command) == 'number') then
|
||||||
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
|
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
|
||||||
end
|
end
|
||||||
return ("Error, numeric argument expected, got : %s"):format(tostring(command))
|
return ("Error, numeric argument expected, got : %s"):format(tostring(command))
|
||||||
end
|
end
|
||||||
|
|
||||||
Command = {
|
Command = {
|
||||||
|
|
||||||
new = function(self, o)
|
new = function(self, o)
|
||||||
|
|
||||||
local o = o or {} -- create object if user does not provide one
|
local o = o or {} -- create object if user does not provide one
|
||||||
setmetatable(o, self) -- DIY inheritance a'la javascript
|
setmetatable(o, self) -- DIY inheritance a'la javascript
|
||||||
self.__index = self
|
self.__index = self
|
||||||
|
|
||||||
o.cmd = o.cmd or _commands.CMD_UNKNOWN
|
o.cmd = o.cmd or _commands.CMD_UNKNOWN
|
||||||
o.arg1 = o.arg1 or 0
|
o.arg1 = o.arg1 or 0
|
||||||
o.arg2 = o.arg2 or 0
|
o.arg2 = o.arg2 or 0
|
||||||
o.arg3 = o.arg3 or 0
|
o.arg3 = o.arg3 or 0
|
||||||
local data = o.data or "0"
|
local data = o.data or "0"
|
||||||
|
|
||||||
if(type(data) == 'string') then
|
if(type(data) == 'string') then
|
||||||
-- We need to check if it is correct length, otherwise pad it
|
-- We need to check if it is correct length, otherwise pad it
|
||||||
local len = string.len(data)
|
local len = string.len(data)
|
||||||
if(len < 1024) then
|
if(len < 1024) then
|
||||||
--Should be 1024 hex characters to represent 512 bytes of data
|
--Should be 1024 hex characters to represent 512 bytes of data
|
||||||
data = data .. string.rep("0",1024 - len )
|
data = data .. string.rep("0",1024 - len )
|
||||||
end
|
end
|
||||||
if(len > 1024) then
|
if(len > 1024) then
|
||||||
-- OOps, a bit too much data here
|
-- OOps, a bit too much data here
|
||||||
print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) )
|
print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) )
|
||||||
--
|
--
|
||||||
data = data:sub(1,1024)
|
data = data:sub(1,1024)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
|
print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
|
||||||
end
|
end
|
||||||
o.data = data
|
o.data = data
|
||||||
return o
|
return o
|
||||||
end,
|
end,
|
||||||
parse = function (packet)
|
parse = function (packet)
|
||||||
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet)
|
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet)
|
||||||
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
|
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
|
||||||
end
|
end
|
||||||
|
|
||||||
}
|
}
|
||||||
function Command:__tostring()
|
function Command:__tostring()
|
||||||
local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
|
local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
|
||||||
_commands.tostring(self.cmd),
|
_commands.tostring(self.cmd),
|
||||||
tostring(self.arg1),
|
tostring(self.arg1),
|
||||||
tostring(self.arg2),
|
tostring(self.arg2),
|
||||||
tostring(self.arg3),
|
tostring(self.arg3),
|
||||||
tostring(self.data))
|
tostring(self.data))
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
function Command:getBytes()
|
function Command:getBytes()
|
||||||
--If a hex-string has been used
|
--If a hex-string has been used
|
||||||
local data = self.data
|
local data = self.data
|
||||||
local cmd = self.cmd
|
local cmd = self.cmd
|
||||||
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
|
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
|
||||||
return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data);
|
return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data);
|
||||||
end
|
end
|
||||||
return _commands
|
return _commands
|
||||||
|
|
|
@ -185,25 +185,25 @@ local _names = {
|
||||||
|
|
||||||
{"404", "9401", "0030", "earth", "legendary","Bash"},
|
{"404", "9401", "0030", "earth", "legendary","Bash"},
|
||||||
{"416", "a001", "0030", "magic", "legendary", "Spyro"},
|
{"416", "a001", "0030", "magic", "legendary", "Spyro"},
|
||||||
--{"", "", "0030", "magic", "legendary", "Deja Vu"},
|
--{"", "", "0030", "magic", "legendary", "Deja Vu"},
|
||||||
{"419", "a301", "0030", "tech", "legendary", "Trigger Happy"},
|
{"419", "a301", "0030", "tech", "legendary", "Trigger Happy"},
|
||||||
--{"", "", "0030", "tech", "legendary", "bouncer"},
|
--{"", "", "0030", "tech", "legendary", "bouncer"},
|
||||||
--{"", "", "0030", "tech", "legendary", "jawbreaker"},
|
--{"", "", "0030", "tech", "legendary", "jawbreaker"},
|
||||||
{"430", "ae01", "0030", "undead", "legendary", "Chop Chop"},
|
{"430", "ae01", "0030", "undead", "legendary", "Chop Chop"},
|
||||||
--{"", "", "0030", "undead", "legendary", "grim creeper"},
|
--{"", "", "0030", "undead", "legendary", "grim creeper"},
|
||||||
--{"", "", "0030", "undead", "legendary", "night shift"},
|
--{"", "", "0030", "undead", "legendary", "night shift"},
|
||||||
|
|
||||||
--{"", "", "0030", "air", "legendary", "blades"},
|
--{"", "", "0030", "air", "legendary", "blades"},
|
||||||
--{"", "", "0030", "air", "legendary", "jet vac"},
|
--{"", "", "0030", "air", "legendary", "jet vac"},
|
||||||
--{"", "", "0030", "air", "legendary", "Free Ranger"},
|
--{"", "", "0030", "air", "legendary", "Free Ranger"},
|
||||||
--{"", "", "0030", "life", "legendary", "stealth elf"},
|
--{"", "", "0030", "life", "legendary", "stealth elf"},
|
||||||
--{"", "", "0030", "life", "legendary", "Bushwhack"},
|
--{"", "", "0030", "life", "legendary", "Bushwhack"},
|
||||||
--{"", "", "0030", "fire", "legendary", "ignitor"},
|
--{"", "", "0030", "fire", "legendary", "ignitor"},
|
||||||
--{"", "", "0030", "water", "legendary", "slam bam"},
|
--{"", "", "0030", "water", "legendary", "slam bam"},
|
||||||
--{"", "", "0030", "water", "legendary", "chill"},
|
--{"", "", "0030", "water", "legendary", "chill"},
|
||||||
|
|
||||||
|
--{"", "", "0030", "", "legendary", "zoo lou"},
|
||||||
|
|
||||||
--{"", "", "0030", "", "legendary", "zoo lou"},
|
|
||||||
|
|
||||||
{"450", "c201", "0030", "air", "trapmaster", "Gusto"},
|
{"450", "c201", "0030", "air", "trapmaster", "Gusto"},
|
||||||
--{"450", "c201", "0234", "air", "trapmaster", "Special Gusto"},
|
--{"450", "c201", "0234", "air", "trapmaster", "Special Gusto"},
|
||||||
{"451", "c301", "0030", "air", "trapmaster", "Thunderbolt"},
|
{"451", "c301", "0030", "air", "trapmaster", "Thunderbolt"},
|
||||||
|
@ -453,23 +453,23 @@ local _names = {
|
||||||
|
|
||||||
local function find( main, sub)
|
local function find( main, sub)
|
||||||
main = main:lower()
|
main = main:lower()
|
||||||
sub = sub:lower()
|
sub = sub:lower()
|
||||||
for k, v in pairs(_names) do
|
for k, v in pairs(_names) do
|
||||||
if ( v[2]:lower() == main and v[3]:lower() == sub) then
|
if ( v[2]:lower() == main and v[3]:lower() == sub) then
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local function list()
|
local function list()
|
||||||
print ("Type\tSub\tElement\tGame Name")
|
print ("Type\tSub\tElement\tGame Name")
|
||||||
print (string.rep('=', 54))
|
print (string.rep('=', 54))
|
||||||
for k, v in pairs(_names) do
|
for k, v in pairs(_names) do
|
||||||
print(("%s\t%s\t%s\t%-9s\t%s"):format(v[2],v[3],v[4], v[5], v[6] ))
|
print(("%s\t%s\t%s\t%-9s\t%s"):format(v[2],v[3],v[4], v[5], v[6] ))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Find = find,
|
Find = find,
|
||||||
List = list,
|
List = list,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--[[
|
--[[
|
||||||
decimal, di edition, model name
|
decimal, di edition, model name
|
||||||
--]]
|
--]]
|
||||||
local _names = {
|
local _names = {
|
||||||
{"1000001","1","Mr. Incredible"},
|
{"1000001","1","Mr. Incredible"},
|
||||||
|
@ -319,8 +319,8 @@ local _names = {
|
||||||
{"4000226","3","?? unknown ??"},
|
{"4000226","3","?? unknown ??"},
|
||||||
{"4000227","3","?? unknown ??"},
|
{"4000227","3","?? unknown ??"},
|
||||||
{"4000229","3","Quad Jumper"},
|
{"4000229","3","Quad Jumper"},
|
||||||
--[[
|
--[[
|
||||||
these below are Portals. Not to be used for tags.
|
these below are Portals. Not to be used for tags.
|
||||||
--]]
|
--]]
|
||||||
{"8032384","0","Infinity Base - 3DS"},
|
{"8032384","0","Infinity Base - 3DS"},
|
||||||
{"8032385","0","Infinity Base - Xbox"},
|
{"8032385","0","Infinity Base - Xbox"},
|
||||||
|
@ -332,21 +332,21 @@ local _names = {
|
||||||
local function find( main )
|
local function find( main )
|
||||||
main = main:lower()
|
main = main:lower()
|
||||||
for k, v in pairs(_names) do
|
for k, v in pairs(_names) do
|
||||||
if ( v[1]:lower() == main ) then
|
if ( v[1]:lower() == main ) then
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local function list()
|
local function list()
|
||||||
print ("Type\tEdition\t Model name")
|
print ("Type\tEdition\t Model name")
|
||||||
print (string.rep('=', 54))
|
print (string.rep('=', 54))
|
||||||
for k, v in pairs(_names) do
|
for k, v in pairs(_names) do
|
||||||
print(("%s\t%s\t%s"):format(v[1],v[2],v[3] ))
|
print(("%s\t%s\t%s"):format(v[1],v[2],v[3] ))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Find = find,
|
Find = find,
|
||||||
List = list,
|
List = list,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,19 @@ https://github.com/attractivechaos/klib/blob/master/lua/klib.lua
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk>
|
Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
@ -56,8 +56,8 @@ local function getopt(args, ostr)
|
||||||
return function ()
|
return function ()
|
||||||
if place == 0 then -- update scanning pointer
|
if place == 0 then -- update scanning pointer
|
||||||
place = 1
|
place = 1
|
||||||
if #args == 0
|
if #args == 0
|
||||||
or args[1]:sub(1, 1) ~= '-' then
|
or args[1]:sub(1, 1) ~= '-' then
|
||||||
place = 0; return nil end
|
place = 0; return nil end
|
||||||
if #args[1] >= 2 then
|
if #args[1] >= 2 then
|
||||||
place = place + 1
|
place = place + 1
|
||||||
|
@ -96,12 +96,12 @@ local function getopt(args, ostr)
|
||||||
if ostr:sub(1, 1) == ':' then return ':' end
|
if ostr:sub(1, 1) == ':' then return ':' end
|
||||||
return '?';
|
return '?';
|
||||||
else arg = args[1] end
|
else arg = args[1] end
|
||||||
end
|
end
|
||||||
table.remove(args, 1);
|
table.remove(args, 1);
|
||||||
place = 0;
|
place = 0;
|
||||||
end
|
end
|
||||||
return optopt, arg;
|
return optopt, arg;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return { getopt = getopt }
|
return { getopt = getopt }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
--[[
|
--[[
|
||||||
THIS IS WORK IN PROGREESS, very much not finished.
|
THIS IS WORK IN PROGREESS, very much not finished.
|
||||||
|
|
||||||
This library utilises other libraries under the hood, but can be used as a generic reader for 13.56MHz tags.
|
This library utilises other libraries under the hood, but can be used as a generic reader for 13.56MHz tags.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local reader14443A = require('read14a')
|
local reader14443A = require('read14a')
|
||||||
|
@ -10,26 +10,26 @@ local reader15693 = require('read15')
|
||||||
|
|
||||||
---
|
---
|
||||||
-- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
|
-- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
|
||||||
-- what tag it is.
|
-- what tag it is.
|
||||||
--
|
--
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successfull: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function waitForTag()
|
local function waitForTag()
|
||||||
print("Waiting for card... press any key to quit")
|
print("Waiting for card... press any key to quit")
|
||||||
local readers = {reader14443A, reader14443B, reader15693}
|
local readers = {reader14443A, reader14443B, reader15693}
|
||||||
local i = 0;
|
local i = 0;
|
||||||
while not core.ukbhit() do
|
while not core.ukbhit() do
|
||||||
i = (i % 3) +1
|
i = (i % 3) +1
|
||||||
r = readers[i]
|
r = readers[i]
|
||||||
print("Reading with ",i)
|
print("Reading with ",i)
|
||||||
res, err = r.read()
|
res, err = r.read()
|
||||||
if res then return res end
|
if res then return res end
|
||||||
print(err)
|
print(err)
|
||||||
-- err means that there was no response from card
|
-- err means that there was no response from card
|
||||||
end
|
end
|
||||||
return nil, "Aborted by user"
|
return nil, "Aborted by user"
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
waitForTag = waitForTag,
|
waitForTag = waitForTag,
|
||||||
}
|
}
|
|
@ -2,154 +2,154 @@ bin = require('bin')
|
||||||
|
|
||||||
|
|
||||||
-------------------------------
|
-------------------------------
|
||||||
-- Some utilities
|
-- Some utilities
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
---
|
---
|
||||||
-- A debug printout-function
|
-- A debug printout-function
|
||||||
local function dbg(args)
|
local function dbg(args)
|
||||||
|
|
||||||
if type(args) == "table" then
|
if type(args) == "table" then
|
||||||
local i = 1
|
local i = 1
|
||||||
while args[i] do
|
while args[i] do
|
||||||
print("###", args[i])
|
print("###", args[i])
|
||||||
i = i+1
|
i = i+1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print("###", args)
|
print("###", args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
---
|
---
|
||||||
-- This is only meant to be used when errors occur
|
-- This is only meant to be used when errors occur
|
||||||
local function oops(err)
|
local function oops(err)
|
||||||
print("ERROR: ",err)
|
print("ERROR: ",err)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
|
|
||||||
local function save_HTML(javascript, filename)
|
local function save_HTML(javascript, filename)
|
||||||
|
|
||||||
-- Read the HTML-skel file
|
-- Read the HTML-skel file
|
||||||
local skel = require("htmlskel")
|
local skel = require("htmlskel")
|
||||||
html = skel.getHTML(javascript);
|
html = skel.getHTML(javascript);
|
||||||
|
|
||||||
-- Open the output file
|
-- Open the output file
|
||||||
|
|
||||||
local outfile = io.open(filename, "w")
|
|
||||||
if outfile == nil then
|
|
||||||
return oops(string.format("Could not write to file %s",tostring(filename)))
|
|
||||||
end
|
|
||||||
-- Write the data into it
|
|
||||||
outfile:write(html)
|
|
||||||
io.close(outfile)
|
|
||||||
|
|
||||||
-- Done
|
local outfile = io.open(filename, "w")
|
||||||
return filename
|
if outfile == nil then
|
||||||
|
return oops(string.format("Could not write to file %s",tostring(filename)))
|
||||||
|
end
|
||||||
|
-- Write the data into it
|
||||||
|
outfile:write(html)
|
||||||
|
io.close(outfile)
|
||||||
|
|
||||||
|
-- Done
|
||||||
|
return filename
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function save_TEXT(data,filename)
|
local function save_TEXT(data,filename)
|
||||||
-- Open the output file
|
-- Open the output file
|
||||||
local outfile = io.open(filename, "w")
|
local outfile = io.open(filename, "w")
|
||||||
if outfile == nil then
|
if outfile == nil then
|
||||||
return oops(string.format("Could not write to file %s",tostring(filename)))
|
return oops(string.format("Could not write to file %s",tostring(filename)))
|
||||||
end
|
end
|
||||||
|
|
||||||
outfile:write(data)
|
outfile:write(data)
|
||||||
io.close(outfile)
|
io.close(outfile)
|
||||||
return filename
|
return filename
|
||||||
end
|
end
|
||||||
|
|
||||||
local function save_BIN(data, filename)
|
local function save_BIN(data, filename)
|
||||||
-- Open the output file
|
-- Open the output file
|
||||||
|
|
||||||
local outfile = io.open(filename, "wb")
|
local outfile = io.open(filename, "wb")
|
||||||
if outfile == nil then
|
if outfile == nil then
|
||||||
return oops(string.format("Could not write to file %s",tostring(filename)))
|
return oops(string.format("Could not write to file %s",tostring(filename)))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Write the data into it
|
-- Write the data into it
|
||||||
local i = 1
|
local i = 1
|
||||||
while data[i] do
|
while data[i] do
|
||||||
outfile:write(data[i])
|
outfile:write(data[i])
|
||||||
i = i+1
|
i = i+1
|
||||||
end
|
end
|
||||||
|
|
||||||
io.close(outfile)
|
io.close(outfile)
|
||||||
return filename
|
return filename
|
||||||
end
|
end
|
||||||
|
|
||||||
local function convert_ascii_dump_to_JS(infile)
|
local function convert_ascii_dump_to_JS(infile)
|
||||||
local t = infile:read("*all")
|
local t = infile:read("*all")
|
||||||
local cleaned
|
local cleaned
|
||||||
local output = "[";
|
local output = "[";
|
||||||
for line in string.gmatch(t, "[^\n]+") do
|
for line in string.gmatch(t, "[^\n]+") do
|
||||||
if string.byte(line,1) ~= string.byte("+",1) then
|
if string.byte(line,1) ~= string.byte("+",1) then
|
||||||
cleaned = (line or ''):gsub('%s+','')
|
cleaned = (line or ''):gsub('%s+','')
|
||||||
output = output .. "'"..cleaned.."',\n"
|
output = output .. "'"..cleaned.."',\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
output = output .. "]"
|
output = output .. "]"
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
local function convert_binary_dump_to_JS(infile, blockLen)
|
local function convert_binary_dump_to_JS(infile, blockLen)
|
||||||
local bindata = infile:read("*all")
|
local bindata = infile:read("*all")
|
||||||
len = string.len(bindata)
|
len = string.len(bindata)
|
||||||
|
|
||||||
if len % blockLen ~= 0 then
|
if len % blockLen ~= 0 then
|
||||||
return oops(("Bad data, length (%d) should be a multiple of blocklen (%d)"):format(len, blockLen))
|
return oops(("Bad data, length (%d) should be a multiple of blocklen (%d)"):format(len, blockLen))
|
||||||
end
|
end
|
||||||
|
|
||||||
local _,hex = bin.unpack(("H%d"):format(len),bindata)
|
local _,hex = bin.unpack(("H%d"):format(len),bindata)
|
||||||
|
|
||||||
-- Now that we've converted binary data into hex, we doubled the size.
|
-- Now that we've converted binary data into hex, we doubled the size.
|
||||||
-- One byte, like 0xDE is now
|
-- One byte, like 0xDE is now
|
||||||
-- the characters 'D' and 'E' : one byte each.
|
-- the characters 'D' and 'E' : one byte each.
|
||||||
-- Thus:
|
-- Thus:
|
||||||
blockLen = blockLen * 2
|
blockLen = blockLen * 2
|
||||||
|
|
||||||
local js,i = "[";
|
local js,i = "[";
|
||||||
for i = 1, string.len(hex),blockLen do
|
for i = 1, string.len(hex),blockLen do
|
||||||
js = js .."'" ..string.sub(hex,i,i+blockLen -1).."',\n"
|
js = js .."'" ..string.sub(hex,i,i+blockLen -1).."',\n"
|
||||||
end
|
end
|
||||||
js = js .. "]"
|
js = js .. "]"
|
||||||
return js
|
return js
|
||||||
end
|
end
|
||||||
|
|
||||||
local function convert_ascii_dump_to_BIN(infile)
|
local function convert_ascii_dump_to_BIN(infile)
|
||||||
local t = infile:read("*all")
|
local t = infile:read("*all")
|
||||||
local cleaned
|
local cleaned
|
||||||
local output = {};
|
local output = {};
|
||||||
for line in string.gmatch(t, "[^\n]+") do
|
for line in string.gmatch(t, "[^\n]+") do
|
||||||
if string.byte(line) ~= string.byte("+") then
|
if string.byte(line) ~= string.byte("+") then
|
||||||
cleaned = (line or ''):gsub('%s+','')
|
cleaned = (line or ''):gsub('%s+','')
|
||||||
for c in cleaned:gmatch('..') do
|
for c in cleaned:gmatch('..') do
|
||||||
output[#output+1] = string.char( tonumber(c,16) )
|
output[#output+1] = string.char( tonumber(c,16) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Converts a .eml-file into a HTML/Javascript file.
|
-- Converts a .eml-file into a HTML/Javascript file.
|
||||||
-- @param input the file to convert
|
-- @param input the file to convert
|
||||||
-- @param output the file to write to
|
-- @param output the file to write to
|
||||||
-- @return the name of the new file.
|
-- @return the name of the new file.
|
||||||
local function convert_eml_to_html(input, output)
|
local function convert_eml_to_html(input, output)
|
||||||
input = input or 'dumpdata.eml'
|
input = input or 'dumpdata.eml'
|
||||||
output = output or input .. 'html'
|
output = output or input .. 'html'
|
||||||
|
|
||||||
local infile = io.open(input, "r")
|
local infile = io.open(input, "r")
|
||||||
if infile == nil then
|
if infile == nil then
|
||||||
return oops(string.format("Could not read file %s",tostring(input)))
|
return oops(string.format("Could not read file %s",tostring(input)))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Read file, get JS
|
-- Read file, get JS
|
||||||
local javascript = convert_ascii_dump_to_JS(infile)
|
local javascript = convert_ascii_dump_to_JS(infile)
|
||||||
io.close(infile)
|
io.close(infile)
|
||||||
return save_HTML(javascript, output )
|
return save_HTML(javascript, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Converts a binary dump into HTML/Javascript file
|
--- Converts a binary dump into HTML/Javascript file
|
||||||
|
@ -157,46 +157,46 @@ end
|
||||||
-- @param output the file to write to
|
-- @param output the file to write to
|
||||||
-- @param blockLen, the length of each block. Defaults to 16 bytes
|
-- @param blockLen, the length of each block. Defaults to 16 bytes
|
||||||
local function convert_bin_to_html(input, output, blockLen)
|
local function convert_bin_to_html(input, output, blockLen)
|
||||||
input = input or 'dumpdata.bin'
|
input = input or 'dumpdata.bin'
|
||||||
blockLen = blockLen or 16
|
blockLen = blockLen or 16
|
||||||
output = output or input .. 'html'
|
output = output or input .. 'html'
|
||||||
|
|
||||||
local infile = io.open(input, "rb")
|
local infile = io.open(input, "rb")
|
||||||
if infile == nil then
|
if infile == nil then
|
||||||
return oops(string.format("Could not read file %s",tostring(input)))
|
return oops(string.format("Could not read file %s",tostring(input)))
|
||||||
end
|
end
|
||||||
-- Read file, get JS
|
-- Read file, get JS
|
||||||
local javascript = convert_binary_dump_to_JS(infile, blockLen)
|
local javascript = convert_binary_dump_to_JS(infile, blockLen)
|
||||||
io.close(infile)
|
io.close(infile)
|
||||||
|
|
||||||
return save_HTML(javascript, output )
|
return save_HTML(javascript, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Converts a eml dump into a binary file
|
--- Converts a eml dump into a binary file
|
||||||
-- @param input the file containing the eml-dump (defaults to dumpdata.eml)
|
-- @param input the file containing the eml-dump (defaults to dumpdata.eml)
|
||||||
-- @param output the file to write to ( defaults to dumpdata.bin)
|
-- @param output the file to write to ( defaults to dumpdata.bin)
|
||||||
local function convert_eml_to_bin(input, output)
|
local function convert_eml_to_bin(input, output)
|
||||||
input = input or 'dumpdata.eml'
|
input = input or 'dumpdata.eml'
|
||||||
output = output or 'dumpdata.bin'
|
output = output or 'dumpdata.bin'
|
||||||
|
|
||||||
local infile = io.open(input, "rb")
|
local infile = io.open(input, "rb")
|
||||||
if infile == nil then
|
if infile == nil then
|
||||||
return oops(string.format("Could not read file %s",tostring(input)))
|
return oops(string.format("Could not read file %s",tostring(input)))
|
||||||
end
|
end
|
||||||
-- Read file, get BIN
|
-- Read file, get BIN
|
||||||
local data = convert_ascii_dump_to_BIN(infile)
|
local data = convert_ascii_dump_to_BIN(infile)
|
||||||
io.close(infile)
|
io.close(infile)
|
||||||
|
|
||||||
return save_BIN(data, output )
|
return save_BIN(data, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
convert_bin_to_html = convert_bin_to_html,
|
convert_bin_to_html = convert_bin_to_html,
|
||||||
convert_eml_to_html = convert_eml_to_html,
|
convert_eml_to_html = convert_eml_to_html,
|
||||||
convert_eml_to_bin = convert_eml_to_bin,
|
convert_eml_to_bin = convert_eml_to_bin,
|
||||||
SaveAsBinary = save_BIN,
|
SaveAsBinary = save_BIN,
|
||||||
SaveAsText = save_TEXT,
|
SaveAsText = save_TEXT,
|
||||||
SaveAsBinary = save_BIN,
|
SaveAsBinary = save_BIN,
|
||||||
SaveAsText = save_TEXT,
|
SaveAsText = save_TEXT,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,360 +2,360 @@ local skel_1 = [[
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var dictionary = {}
|
var dictionary = {}
|
||||||
function add(commaSeparated)
|
function add(commaSeparated)
|
||||||
{
|
{
|
||||||
var fields = commaSeparated.split(",");
|
var fields = commaSeparated.split(",");
|
||||||
var manufacturerCode = fields[0];
|
var manufacturerCode = fields[0];
|
||||||
var modelCode = fields[1];
|
var modelCode = fields[1];
|
||||||
var modelSubCode= fields[2];
|
var modelSubCode= fields[2];
|
||||||
var modelName = fields[3];
|
var modelName = fields[3];
|
||||||
var ATQA = fields[4];
|
var ATQA = fields[4];
|
||||||
var SAK = fields[5];
|
var SAK = fields[5];
|
||||||
|
|
||||||
//In the data below, wrong endian is used. Mifare is
|
//In the data below, wrong endian is used. Mifare is
|
||||||
// written as "0004" instead of "0400", so we need to
|
// written as "0004" instead of "0400", so we need to
|
||||||
// flip it
|
// flip it
|
||||||
ATQA = ATQA.substr(2,4)+ATQA.substr(0,2)
|
ATQA = ATQA.substr(2,4)+ATQA.substr(0,2)
|
||||||
|
|
||||||
var info = {
|
var info = {
|
||||||
modelCode : modelCode,
|
modelCode : modelCode,
|
||||||
modelSubCode : modelSubCode,
|
modelSubCode : modelSubCode,
|
||||||
modelName : modelName,
|
modelName : modelName,
|
||||||
ATQA : ATQA,
|
ATQA : ATQA,
|
||||||
SAK : SAK
|
SAK : SAK
|
||||||
}
|
}
|
||||||
console.log("Adding "+modelName+" , "+SAK)
|
console.log("Adding "+modelName+" , "+SAK)
|
||||||
|
|
||||||
dictionary[ATQA] = dictionary[ATQA] || [];
|
dictionary[ATQA] = dictionary[ATQA] || [];
|
||||||
dictionary[ATQA].push(info)
|
dictionary[ATQA].push(info)
|
||||||
}
|
}
|
||||||
function lookup(atqa, sak)
|
function lookup(atqa, sak)
|
||||||
{
|
{
|
||||||
if (!dictionary[atqa]) return "UNKNOWN";
|
if (!dictionary[atqa]) return "UNKNOWN";
|
||||||
|
|
||||||
var possibleMatches = [];
|
var possibleMatches = [];
|
||||||
for(var i = 0 ; i < dictionary[atqa].length ; i++)
|
for(var i = 0 ; i < dictionary[atqa].length ; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
var info = dictionary[atqa][i];
|
var info = dictionary[atqa][i];
|
||||||
console.log("Comparing "+sak+ " with "+ info.SAK);
|
console.log("Comparing "+sak+ " with "+ info.SAK);
|
||||||
if(sak && info.SAK == sak)//exact match
|
if(sak && info.SAK == sak)//exact match
|
||||||
{
|
{
|
||||||
return info.modelName;
|
return info.modelName;
|
||||||
// possibleMatches.push(info.modelName);
|
// possibleMatches.push(info.modelName);
|
||||||
}else //SAK unknown
|
}else //SAK unknown
|
||||||
{
|
{
|
||||||
possibleMatches.push(info.modelName);
|
possibleMatches.push(info.modelName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(possibleMatches.length > 0)
|
if(possibleMatches.length > 0)
|
||||||
return possibleMatches.join(" or ");
|
return possibleMatches.join(" or ");
|
||||||
return "UNKNOWN"
|
return "UNKNOWN"
|
||||||
}
|
}
|
||||||
|
|
||||||
add("04,,,Mifare TNP3xxx Activision 1K,0f01,01");
|
add("04,,,Mifare TNP3xxx Activision 1K,0f01,01");
|
||||||
add("04,,,Mifare Mini,0004,09");
|
add("04,,,Mifare Mini,0004,09");
|
||||||
add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
|
add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
|
||||||
add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
|
add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
|
||||||
add("04,,,Mifare Plus (4 byte UID) 4K SL2,0004,11");
|
add("04,,,Mifare Plus (4 byte UID) 4K SL2,0004,11");
|
||||||
add("04,,,Mifare Plus (4 byte UID) 4K SL1,0004,18");
|
add("04,,,Mifare Plus (4 byte UID) 4K SL1,0004,18");
|
||||||
add("04,,,Mifare Plus (4 byte UID) 2K/4K SL3,0004,20");
|
add("04,,,Mifare Plus (4 byte UID) 2K/4K SL3,0004,20");
|
||||||
add("04,,,Mifare Classic 4K,0002,18");
|
add("04,,,Mifare Classic 4K,0002,18");
|
||||||
add("xx,,,NDEF Tags,0044,00 ");
|
add("xx,,,NDEF Tags,0044,00 ");
|
||||||
add("04,,,Mifare Ultralight/UltralightC,0044,04");
|
add("04,,,Mifare Ultralight/UltralightC,0044,04");
|
||||||
add("04,,,Mifare Plus (7 byte UID) 2K SL1,0042,08");
|
add("04,,,Mifare Plus (7 byte UID) 2K SL1,0042,08");
|
||||||
add("04,,,Mifare Plus (7 byte UID) 2K SL1,0044,08");
|
add("04,,,Mifare Plus (7 byte UID) 2K SL1,0044,08");
|
||||||
add("04,,,Mifare Plus (7 byte UID) 4K SL1,0042,18");
|
add("04,,,Mifare Plus (7 byte UID) 4K SL1,0042,18");
|
||||||
add("04,,,Mifare Plus (7 byte UID) 4K SL1,0044,18");
|
add("04,,,Mifare Plus (7 byte UID) 4K SL1,0044,18");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0042,10");
|
add("04,,,Mifare Plus (7 byte UID),0042,10");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0044,10");
|
add("04,,,Mifare Plus (7 byte UID),0044,10");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0042,11");
|
add("04,,,Mifare Plus (7 byte UID),0042,11");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0044,11");
|
add("04,,,Mifare Plus (7 byte UID),0044,11");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0042,20");
|
add("04,,,Mifare Plus (7 byte UID),0042,20");
|
||||||
add("04,,,Mifare Plus (7 byte UID),0044,20");
|
add("04,,,Mifare Plus (7 byte UID),0044,20");
|
||||||
add("04,,,Mifare DesFire / DesFire EV1,0344,20067577810280");
|
add("04,,,Mifare DesFire / DesFire EV1,0344,20067577810280");
|
||||||
add("04,,,JCOP31,0304,283877B14A434F503331");
|
add("04,,,JCOP31,0304,283877B14A434F503331");
|
||||||
add("04,,,JCOP31 v2.4.1,0048,207877B1024A434F5076323431");
|
add("04,,,JCOP31 v2.4.1,0048,207877B1024A434F5076323431");
|
||||||
add("04,,,JCOP41 v2.2,0048,203833B14A434F503431563232");
|
add("04,,,JCOP41 v2.2,0048,203833B14A434F503431563232");
|
||||||
add("04,,,JCOP41 v2.3.1,0004,283833B14A434F50343156323331");
|
add("04,,,JCOP41 v2.3.1,0004,283833B14A434F50343156323331");
|
||||||
add("05,,,Mifare Classic 1K,0004,88");
|
add("05,,,Mifare Classic 1K,0004,88");
|
||||||
add("40,,,MPCOS,0002,98");
|
add("40,,,MPCOS,0002,98");
|
||||||
add("25,,,Topaz/Topaz512/Jewel,0C00,");
|
add("25,,,Topaz/Topaz512/Jewel,0C00,");
|
||||||
add("1D,,,FM1208SH01,0004,53");
|
add("1D,,,FM1208SH01,0004,53");
|
||||||
add("1D,,,FM1208,0008,20");
|
add("1D,,,FM1208,0008,20");
|
||||||
add("Nokia,,,Mifare Classic 4K emulated by Nokia 6212,0002,38");
|
add("Nokia,,,Mifare Classic 4K emulated by Nokia 6212,0002,38");
|
||||||
add("Nokia,,,Mifare Classic 4K emulated by Nokia 6131,0008,38");
|
add("Nokia,,,Mifare Classic 4K emulated by Nokia 6131,0008,38");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0002");
|
add("04,,,Smart MX with Mifare 4K emulation,0002");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0102");
|
add("04,,,Smart MX with Mifare 4K emulation,0102");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0202");
|
add("04,,,Smart MX with Mifare 4K emulation,0202");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0302");
|
add("04,,,Smart MX with Mifare 4K emulation,0302");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0402");
|
add("04,,,Smart MX with Mifare 4K emulation,0402");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0502");
|
add("04,,,Smart MX with Mifare 4K emulation,0502");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0602");
|
add("04,,,Smart MX with Mifare 4K emulation,0602");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0702");
|
add("04,,,Smart MX with Mifare 4K emulation,0702");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0802");
|
add("04,,,Smart MX with Mifare 4K emulation,0802");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0902");
|
add("04,,,Smart MX with Mifare 4K emulation,0902");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0A02");
|
add("04,,,Smart MX with Mifare 4K emulation,0A02");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0B02");
|
add("04,,,Smart MX with Mifare 4K emulation,0B02");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0C02");
|
add("04,,,Smart MX with Mifare 4K emulation,0C02");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0D02");
|
add("04,,,Smart MX with Mifare 4K emulation,0D02");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0E02");
|
add("04,,,Smart MX with Mifare 4K emulation,0E02");
|
||||||
add("04,,,Smart MX with Mifare 4K emulation,0F02");
|
add("04,,,Smart MX with Mifare 4K emulation,0F02");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0004");
|
add("04,,,Smart MX with Mifare 1K emulation,0004");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0104");
|
add("04,,,Smart MX with Mifare 1K emulation,0104");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0204");
|
add("04,,,Smart MX with Mifare 1K emulation,0204");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0304");
|
add("04,,,Smart MX with Mifare 1K emulation,0304");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0404");
|
add("04,,,Smart MX with Mifare 1K emulation,0404");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0504");
|
add("04,,,Smart MX with Mifare 1K emulation,0504");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0604");
|
add("04,,,Smart MX with Mifare 1K emulation,0604");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0704");
|
add("04,,,Smart MX with Mifare 1K emulation,0704");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0804");
|
add("04,,,Smart MX with Mifare 1K emulation,0804");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0904");
|
add("04,,,Smart MX with Mifare 1K emulation,0904");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0A04");
|
add("04,,,Smart MX with Mifare 1K emulation,0A04");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0B04");
|
add("04,,,Smart MX with Mifare 1K emulation,0B04");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0C04");
|
add("04,,,Smart MX with Mifare 1K emulation,0C04");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0D04");
|
add("04,,,Smart MX with Mifare 1K emulation,0D04");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0E04");
|
add("04,,,Smart MX with Mifare 1K emulation,0E04");
|
||||||
add("04,,,Smart MX with Mifare 1K emulation,0F04");
|
add("04,,,Smart MX with Mifare 1K emulation,0F04");
|
||||||
add("04,,,Smart MX with 7 byte UID,0048");
|
add("04,,,Smart MX with 7 byte UID,0048");
|
||||||
add("04,,,Smart MX with 7 byte UID,0148");
|
add("04,,,Smart MX with 7 byte UID,0148");
|
||||||
add("04,,,Smart MX with 7 byte UID,0248");
|
add("04,,,Smart MX with 7 byte UID,0248");
|
||||||
add("04,,,Smart MX with 7 byte UID,0348");
|
add("04,,,Smart MX with 7 byte UID,0348");
|
||||||
add("04,,,Smart MX with 7 byte UID,0448");
|
add("04,,,Smart MX with 7 byte UID,0448");
|
||||||
add("04,,,Smart MX with 7 byte UID,0548");
|
add("04,,,Smart MX with 7 byte UID,0548");
|
||||||
add("04,,,Smart MX with 7 byte UID,0648");
|
add("04,,,Smart MX with 7 byte UID,0648");
|
||||||
add("04,,,Smart MX with 7 byte UID,0748");
|
add("04,,,Smart MX with 7 byte UID,0748");
|
||||||
add("04,,,Smart MX with 7 byte UID,0848");
|
add("04,,,Smart MX with 7 byte UID,0848");
|
||||||
add("04,,,Smart MX with 7 byte UID,0948");
|
add("04,,,Smart MX with 7 byte UID,0948");
|
||||||
add("04,,,Smart MX with 7 byte UID,0A48");
|
add("04,,,Smart MX with 7 byte UID,0A48");
|
||||||
add("04,,,Smart MX with 7 byte UID,0B48");
|
add("04,,,Smart MX with 7 byte UID,0B48");
|
||||||
add("04,,,Smart MX with 7 byte UID,0C48");
|
add("04,,,Smart MX with 7 byte UID,0C48");
|
||||||
add("04,,,Smart MX with 7 byte UID,0D48");
|
add("04,,,Smart MX with 7 byte UID,0D48");
|
||||||
add("04,,,Smart MX with 7 byte UID,0E48");
|
add("04,,,Smart MX with 7 byte UID,0E48");
|
||||||
add("04,,,Smart MX with 7 byte UID,0F48");
|
add("04,,,Smart MX with 7 byte UID,0F48");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
background-color: #2F3440;
|
background-color: #2F3440;
|
||||||
background-color:#232323;
|
background-color:#232323;
|
||||||
color : #F5E5C0;
|
color : #F5E5C0;
|
||||||
xtext-transform: uppercase;
|
xtext-transform: uppercase;
|
||||||
font-size: 1.05em;
|
font-size: 1.05em;
|
||||||
font-family: monospace,Arial;
|
font-family: monospace,Arial;
|
||||||
}
|
}
|
||||||
table{
|
table{
|
||||||
float:left;
|
float:left;
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
}
|
}
|
||||||
td {
|
td {
|
||||||
empty-cells: show;
|
empty-cells: show;
|
||||||
}
|
}
|
||||||
td.blockzero, .turqoise{
|
td.blockzero, .turqoise{
|
||||||
color: rgb(140, 245, 193);
|
color: rgb(140, 245, 193);
|
||||||
}
|
}
|
||||||
td.key_a, .yellow{
|
td.key_a, .yellow{
|
||||||
color : #F8CA4D;
|
color : #F8CA4D;
|
||||||
}
|
}
|
||||||
td.key_b, .blue{
|
td.key_b, .blue{
|
||||||
color : #3F5666;
|
color : #3F5666;
|
||||||
}
|
}
|
||||||
td.accessconditions, .red{
|
td.accessconditions, .red{
|
||||||
color : #EA6045;
|
color : #EA6045;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.sectorhdr{
|
|
||||||
border-top: 1px solid white;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
/** Jquery for the poor **/
|
|
||||||
function dc(x){return document.createElement(x)}
|
|
||||||
|
|
||||||
function tr(table){
|
td.sectorhdr{
|
||||||
var row = dc('tr');
|
border-top: 1px solid white;
|
||||||
table.appendChild(row);
|
}
|
||||||
return row;
|
</style>
|
||||||
}
|
<script>
|
||||||
function td(row, text){
|
/** Jquery for the poor **/
|
||||||
var tdata = dc('td');
|
function dc(x){return document.createElement(x)}
|
||||||
row.appendChild(tdata);
|
|
||||||
tdata.appendChild(document.createTextNode(text))
|
|
||||||
return tdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
function tr(table){
|
||||||
* The identifiers that determine how to highlight data and present information
|
var row = dc('tr');
|
||||||
**/
|
table.appendChild(row);
|
||||||
var identifiers = [
|
return row;
|
||||||
function(data)
|
}
|
||||||
{
|
function td(row, text){
|
||||||
// Should be 32 characters long ( 16 bytes per block)
|
var tdata = dc('td');
|
||||||
if(data[0].length != 32) { return false; }
|
row.appendChild(tdata);
|
||||||
// ... add more checks if necessary ...
|
tdata.appendChild(document.createTextNode(text))
|
||||||
|
return tdata;
|
||||||
|
}
|
||||||
|
|
||||||
var info = {Type : "Mifare"}
|
/**
|
||||||
info['Size'] = (data[0].length / 2 * data.length) + " Bytes";
|
* The identifiers that determine how to highlight data and present information
|
||||||
info['UID'] = data[0].substring(0,8);
|
**/
|
||||||
info['SAK'] = data[0].substring(10,12);
|
var identifiers = [
|
||||||
info['ATQA'] = data[0].substring(12,16);
|
function(data)
|
||||||
|
{
|
||||||
|
// Should be 32 characters long ( 16 bytes per block)
|
||||||
|
if(data[0].length != 32) { return false; }
|
||||||
|
// ... add more checks if necessary ...
|
||||||
|
|
||||||
info['Name'] = lookup(info.ATQA, info.SAK);
|
var info = {Type : "Mifare"}
|
||||||
return {info: info, highlighter : mifareHighlighter }
|
info['Size'] = (data[0].length / 2 * data.length) + " Bytes";
|
||||||
},
|
info['UID'] = data[0].substring(0,8);
|
||||||
function(data)
|
info['SAK'] = data[0].substring(10,12);
|
||||||
{
|
info['ATQA'] = data[0].substring(12,16);
|
||||||
// Should be 8 characters long ( 4 bytes per block)
|
|
||||||
if(data[0].length != 8) { return false; }
|
|
||||||
// ... add more checks if necessary ...
|
|
||||||
var info = {Type : "NDEF"}
|
|
||||||
info['Size'] = (data[0].length / 2 * data.length) + " Bytes";
|
|
||||||
|
|
||||||
return {info: info, highlighter : ndefHighligheter }
|
info['Name'] = lookup(info.ATQA, info.SAK);
|
||||||
},
|
return {info: info, highlighter : mifareHighlighter }
|
||||||
|
},
|
||||||
|
function(data)
|
||||||
|
{
|
||||||
|
// Should be 8 characters long ( 4 bytes per block)
|
||||||
|
if(data[0].length != 8) { return false; }
|
||||||
|
// ... add more checks if necessary ...
|
||||||
|
var info = {Type : "NDEF"}
|
||||||
|
info['Size'] = (data[0].length / 2 * data.length) + " Bytes";
|
||||||
|
|
||||||
function(data)
|
return {info: info, highlighter : ndefHighligheter }
|
||||||
{//This is the catch-all
|
},
|
||||||
return {info: {type : "Unknown"}, highlighter : noHighlighter}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
function(data)
|
||||||
* Helper function to convert bin-data into printable chars
|
{//This is the catch-all
|
||||||
**/
|
return {info: {type : "Unknown"}, highlighter : noHighlighter}
|
||||||
|
}
|
||||||
function to_ascii(hexval)
|
]
|
||||||
{
|
|
||||||
var intval = parseInt(hexval,16);
|
|
||||||
if(intval > 31 && intval < 127)
|
|
||||||
{
|
|
||||||
return String.fromCharCode(intval);
|
|
||||||
}
|
|
||||||
return ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function loadIntoTable(data, info, ascii)
|
/**
|
||||||
{
|
* Helper function to convert bin-data into printable chars
|
||||||
var t = dc("table")
|
**/
|
||||||
for(var i = 0 ; i < data.length ; i++)
|
|
||||||
{
|
|
||||||
line = data[i];
|
|
||||||
var row = tr(t);
|
|
||||||
var bytes = line.match(/(.{1,2})/g);
|
|
||||||
for(var b = 0 ; b < bytes.length ; b++)
|
|
||||||
{
|
|
||||||
var elem = td(row, ascii ? to_ascii(bytes[b]) : bytes[b]);
|
|
||||||
info.highlighter.addClass(elem,i,b, bytes[b]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.body.appendChild(t);
|
|
||||||
}
|
|
||||||
function loadGeneralInfo(data, info)
|
|
||||||
{
|
|
||||||
var t = dc("table");
|
|
||||||
for (var key in info)
|
|
||||||
{
|
|
||||||
var row = tr(t);
|
|
||||||
td(row,key);
|
|
||||||
td(row,info[key]);
|
|
||||||
}
|
|
||||||
document.body.appendChild(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle(dump)
|
function to_ascii(hexval)
|
||||||
{
|
{
|
||||||
var data = dump.data;
|
var intval = parseInt(hexval,16);
|
||||||
var info = null;
|
if(intval > 31 && intval < 127)
|
||||||
for(var i = 0; i < identifiers.length && !info; i++)
|
{
|
||||||
info = identifiers[i](data);
|
return String.fromCharCode(intval);
|
||||||
|
}
|
||||||
|
return ".";
|
||||||
|
}
|
||||||
|
|
||||||
console.log(info);
|
|
||||||
|
|
||||||
loadIntoTable(data, info, false);
|
function loadIntoTable(data, info, ascii)
|
||||||
loadIntoTable(data, info, true);
|
{
|
||||||
loadGeneralInfo(data, info.info);
|
var t = dc("table")
|
||||||
|
for(var i = 0 ; i < data.length ; i++)
|
||||||
|
{
|
||||||
|
line = data[i];
|
||||||
|
var row = tr(t);
|
||||||
|
var bytes = line.match(/(.{1,2})/g);
|
||||||
|
for(var b = 0 ; b < bytes.length ; b++)
|
||||||
|
{
|
||||||
|
var elem = td(row, ascii ? to_ascii(bytes[b]) : bytes[b]);
|
||||||
|
info.highlighter.addClass(elem,i,b, bytes[b]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.body.appendChild(t);
|
||||||
|
}
|
||||||
|
function loadGeneralInfo(data, info)
|
||||||
|
{
|
||||||
|
var t = dc("table");
|
||||||
|
for (var key in info)
|
||||||
|
{
|
||||||
|
var row = tr(t);
|
||||||
|
td(row,key);
|
||||||
|
td(row,info[key]);
|
||||||
|
}
|
||||||
|
document.body.appendChild(t);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
function handle(dump)
|
||||||
var noHighlighter = {
|
{
|
||||||
addClass : function(el ,line, byte)
|
var data = dump.data;
|
||||||
{
|
var info = null;
|
||||||
return;
|
for(var i = 0; i < identifiers.length && !info; i++)
|
||||||
}
|
info = identifiers[i](data);
|
||||||
};
|
|
||||||
var ndefHighligheter = {
|
|
||||||
addClass : function(el ,line, byte, value)
|
|
||||||
{
|
|
||||||
if(line < 3)
|
|
||||||
{
|
|
||||||
el.className += " red";
|
|
||||||
}
|
|
||||||
if ( line == 3)
|
|
||||||
{
|
|
||||||
console.log(value);
|
|
||||||
if( byte == 0 && "e1" == value.toLowerCase()) el.className += " turqoise";
|
|
||||||
if( byte == 1 ) el.className += " yellow";
|
|
||||||
if( byte == 2 ) el.className += " blue";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var mifareHighlighter = {
|
|
||||||
addClass : function(el ,line, byte)
|
|
||||||
{
|
|
||||||
if (line == 0)
|
|
||||||
{
|
|
||||||
el.className += " blockzero";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(line < 128){
|
|
||||||
linesPerSector = 4;
|
|
||||||
} else {
|
|
||||||
//Quadruple size sectors
|
|
||||||
linesPerSector = 16;
|
|
||||||
line = line - 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(line % linesPerSector == 0)
|
console.log(info);
|
||||||
{
|
|
||||||
el.className += " sectorhdr";
|
|
||||||
}
|
|
||||||
if(line % linesPerSector == (linesPerSector -1))
|
|
||||||
{
|
|
||||||
el.className += " sectortrailer";
|
|
||||||
if(byte == undefined)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(byte < 6) el.className += " key_a";
|
loadIntoTable(data, info, false);
|
||||||
else if(byte < 10) el.className += " accessconditions";
|
loadIntoTable(data, info, true);
|
||||||
else el.className += " key_b";
|
loadGeneralInfo(data, info.info);
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
var noHighlighter = {
|
||||||
|
addClass : function(el ,line, byte)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ndefHighligheter = {
|
||||||
|
addClass : function(el ,line, byte, value)
|
||||||
|
{
|
||||||
|
if(line < 3)
|
||||||
|
{
|
||||||
|
el.className += " red";
|
||||||
|
}
|
||||||
|
if ( line == 3)
|
||||||
|
{
|
||||||
|
console.log(value);
|
||||||
|
if( byte == 0 && "e1" == value.toLowerCase()) el.className += " turqoise";
|
||||||
|
if( byte == 1 ) el.className += " yellow";
|
||||||
|
if( byte == 2 ) el.className += " blue";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var mifareHighlighter = {
|
||||||
|
addClass : function(el ,line, byte)
|
||||||
|
{
|
||||||
|
if (line == 0)
|
||||||
|
{
|
||||||
|
el.className += " blockzero";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(line < 128){
|
||||||
|
linesPerSector = 4;
|
||||||
|
} else {
|
||||||
|
//Quadruple size sectors
|
||||||
|
linesPerSector = 16;
|
||||||
|
line = line - 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(line % linesPerSector == 0)
|
||||||
|
{
|
||||||
|
el.className += " sectorhdr";
|
||||||
|
}
|
||||||
|
if(line % linesPerSector == (linesPerSector -1))
|
||||||
|
{
|
||||||
|
el.className += " sectortrailer";
|
||||||
|
if(byte == undefined)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(byte < 6) el.className += " key_a";
|
||||||
|
else if(byte < 10) el.className += " accessconditions";
|
||||||
|
else el.className += " key_b";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
<script>
|
<script>
|
||||||
var x = { data :
|
var x = { data :
|
||||||
]]
|
]]
|
||||||
local skel_2 = [[
|
local skel_2 = [[
|
||||||
|
|
||||||
};
|
};
|
||||||
handle(x);
|
handle(x);
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
]]
|
]]
|
||||||
local function getHTML(data)
|
local function getHTML(data)
|
||||||
return skel_1 .. data .. skel_2
|
return skel_1 .. data .. skel_2
|
||||||
end
|
end
|
||||||
|
|
||||||
return {getHTML = getHTML}
|
return {getHTML = getHTML}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--[[
|
--[[
|
||||||
This is an experimental lib.
|
This is an experimental lib.
|
||||||
--]]
|
--]]
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
|
|
||||||
|
@ -35,60 +35,60 @@ shifts[9]= { 0xD, 0xB, 0x0, 0x6, 0x6, 0x0, 0xB, 0xD, 0xA, 0xC, 0x7, 0x1, 0x1, 0x
|
||||||
shifts[10]= { 0xe, 0x1, 0x1, 0xe, 0x1, 0xe, 0xe, 0x1, 0x1, 0xe, 0xe, 0x1, 0xe, 0x1, 0x1, 0xe }
|
shifts[10]= { 0xe, 0x1, 0x1, 0xe, 0x1, 0xe, 0xe, 0x1, 0x1, 0xe, 0xe, 0x1, 0xe, 0x1, 0x1, 0xe }
|
||||||
|
|
||||||
local function ApplyPermutationAndShifts( pos, value, nibble)
|
local function ApplyPermutationAndShifts( pos, value, nibble)
|
||||||
local shiftbytes = shifts[pos]
|
local shiftbytes = shifts[pos]
|
||||||
local shiftElem = shiftbytes[nibble+1] --one indexed
|
local shiftElem = shiftbytes[nibble+1] --one indexed
|
||||||
local shiftOne = shiftbytes[1]
|
local shiftOne = shiftbytes[1]
|
||||||
local rs = bit32.bxor(value, shiftOne, shiftElem)
|
local rs = bit32.bxor(value, shiftOne, shiftElem)
|
||||||
return rs
|
return rs
|
||||||
end
|
end
|
||||||
|
|
||||||
local function GetOne( uid, block )
|
local function GetOne( uid, block )
|
||||||
|
|
||||||
if uid == nil then return nil, 'empty uid string' end
|
if uid == nil then return nil, 'empty uid string' end
|
||||||
if #uid == 0 then return nil, 'empty uid string' end
|
if #uid == 0 then return nil, 'empty uid string' end
|
||||||
if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end
|
if #uid ~= 8 then return nil, 'uid wrong length. Should be 4 hex bytes' end
|
||||||
if type(block) ~= 'number' then return nil, 'block is not number' end
|
if type(block) ~= 'number' then return nil, 'block is not number' end
|
||||||
if block > 16 or block < 0 then return nil, 'block is out-of-range' end
|
if block > 16 or block < 0 then return nil, 'block is out-of-range' end
|
||||||
|
|
||||||
local s = ('%s%02X'):format(uid,block)
|
|
||||||
local nibble1 = tonumber(s:sub(1,1),16) + 1
|
|
||||||
|
|
||||||
local permuted = ''
|
local s = ('%s%02X'):format(uid,block)
|
||||||
for i = 1, #s do
|
local nibble1 = tonumber(s:sub(1,1),16) + 1
|
||||||
local el_row = shifts[i]
|
|
||||||
local el_value = el_row[nibble1]
|
|
||||||
j = 1
|
|
||||||
while j <= i do
|
|
||||||
if i-j > 0 then
|
|
||||||
local nibble = tonumber(s:sub(j+1,j+1),16)
|
|
||||||
el_value = ApplyPermutationAndShifts(i-j, el_value, nibble)
|
|
||||||
end
|
|
||||||
j = j+1
|
|
||||||
end
|
|
||||||
permuted =('%s%X'):format(permuted,el_value)
|
|
||||||
end
|
|
||||||
|
|
||||||
permuted = 'C2'..permuted
|
local permuted = ''
|
||||||
local crc64numStr = utils.Crc64(permuted)
|
for i = 1, #s do
|
||||||
local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true)
|
local el_row = shifts[i]
|
||||||
local key = utils.ConvertBytesToHex(keybytes)
|
local el_value = el_row[nibble1]
|
||||||
return key:sub(1,12)
|
j = 1
|
||||||
|
while j <= i do
|
||||||
|
if i-j > 0 then
|
||||||
|
local nibble = tonumber(s:sub(j+1,j+1),16)
|
||||||
|
el_value = ApplyPermutationAndShifts(i-j, el_value, nibble)
|
||||||
|
end
|
||||||
|
j = j+1
|
||||||
|
end
|
||||||
|
permuted =('%s%X'):format(permuted,el_value)
|
||||||
|
end
|
||||||
|
|
||||||
|
permuted = 'C2'..permuted
|
||||||
|
local crc64numStr = utils.Crc64(permuted)
|
||||||
|
local keybytes = utils.ConvertAsciiToBytes(crc64numStr, true)
|
||||||
|
local key = utils.ConvertBytesToHex(keybytes)
|
||||||
|
return key:sub(1,12)
|
||||||
end
|
end
|
||||||
|
|
||||||
local PreCalc =
|
local PreCalc =
|
||||||
{
|
{
|
||||||
GetAll = function(id)
|
GetAll = function(id)
|
||||||
if id == nil then return nil, 'empty string' end
|
if id == nil then return nil, 'empty string' end
|
||||||
if #id == 0 then return nil, 'empty string' end
|
if #id == 0 then return nil, 'empty string' end
|
||||||
if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end
|
if #id ~= 8 then return nil, 'wrong length. Should be 4 hex bytes' end
|
||||||
|
|
||||||
local list = '4b0b20107ccb'
|
local list = '4b0b20107ccb'
|
||||||
for i = 1,15 do
|
for i = 1,15 do
|
||||||
local key, err = GetOne(id,i)
|
local key, err = GetOne(id,i)
|
||||||
if not key then return oops(err) end
|
if not key then return oops(err) end
|
||||||
list = list..key
|
list = list..key
|
||||||
end
|
end
|
||||||
return list
|
return list
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
return PreCalc
|
return PreCalc
|
|
@ -1,32 +1,32 @@
|
||||||
--[[
|
--[[
|
||||||
This is a library to read 14443a tags. It can be used something like this
|
This is a library to read 14443a tags. It can be used something like this
|
||||||
|
|
||||||
local reader = require('read14a')
|
local reader = require('read14a')
|
||||||
result, err = reader.read14443a()
|
result, err = reader.read14443a()
|
||||||
if not result then
|
if not result then
|
||||||
print(err)
|
print(err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
print(result.name)
|
print(result.name)
|
||||||
|
|
||||||
--]]
|
--]]
|
||||||
-- Loads the commands-library
|
-- Loads the commands-library
|
||||||
local cmds = require('commands')
|
local cmds = require('commands')
|
||||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||||
local ISO14A_COMMAND = {
|
local ISO14A_COMMAND = {
|
||||||
ISO14A_CONNECT = 1,
|
ISO14A_CONNECT = 1,
|
||||||
ISO14A_NO_DISCONNECT = 2,
|
ISO14A_NO_DISCONNECT = 2,
|
||||||
ISO14A_APDU = 4,
|
ISO14A_APDU = 4,
|
||||||
ISO14A_RAW = 8,
|
ISO14A_RAW = 8,
|
||||||
ISO14A_REQUEST_TRIGGER = 0x10,
|
ISO14A_REQUEST_TRIGGER = 0x10,
|
||||||
ISO14A_APPEND_CRC = 0x20,
|
ISO14A_APPEND_CRC = 0x20,
|
||||||
ISO14A_SET_TIMEOUT = 0x40,
|
ISO14A_SET_TIMEOUT = 0x40,
|
||||||
ISO14A_NO_SELECT = 0x80,
|
ISO14A_NO_SELECT = 0x80,
|
||||||
ISO14A_TOPAZMODE = 0x100,
|
ISO14A_TOPAZMODE = 0x100,
|
||||||
ISO14A_NO_RATS = 0x200
|
ISO14A_NO_RATS = 0x200
|
||||||
}
|
}
|
||||||
|
|
||||||
local ISO14443a_TYPES = {}
|
local ISO14443a_TYPES = {}
|
||||||
ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C | NTAG"
|
ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C | NTAG"
|
||||||
ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
|
ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
|
||||||
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
|
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
|
||||||
|
@ -45,50 +45,50 @@ ISO14443a_TYPES[0x98] = "Gemplus MPCOS"
|
||||||
|
|
||||||
|
|
||||||
local function tostring_14443a(sak)
|
local function tostring_14443a(sak)
|
||||||
return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
|
return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parse14443a(data)
|
local function parse14443a(data)
|
||||||
--[[
|
--[[
|
||||||
|
|
||||||
Based on this struct :
|
Based on this struct :
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
byte_t uid[10];
|
byte_t uid[10];
|
||||||
byte_t uidlen;
|
byte_t uidlen;
|
||||||
byte_t atqa[2];
|
byte_t atqa[2];
|
||||||
byte_t sak;
|
byte_t sak;
|
||||||
byte_t ats_len;
|
byte_t ats_len;
|
||||||
byte_t ats[256];
|
byte_t ats[256];
|
||||||
} __attribute__((__packed__)) iso14a_card_select_t;
|
} __attribute__((__packed__)) iso14a_card_select_t;
|
||||||
|
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
local count, uid, uidlen, atqa, sak, ats_len, ats = bin.unpack('H10CH2CC',data)
|
local count, uid, uidlen, atqa, sak, ats_len, ats = bin.unpack('H10CH2CC',data)
|
||||||
uid = uid:sub(1, 2*uidlen)
|
uid = uid:sub(1, 2*uidlen)
|
||||||
--print("uid, atqa, sak: ",uid, atqa, sak)
|
--print("uid, atqa, sak: ",uid, atqa, sak)
|
||||||
--print("TYPE: ", tostring_1443a(sak))
|
--print("TYPE: ", tostring_1443a(sak))
|
||||||
return { uid = uid, atqa = atqa, sak = sak, name = tostring_14443a(sak), data = data}
|
return { uid = uid, atqa = atqa, sak = sak, name = tostring_14443a(sak), data = data}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sends a USBpacket to the device
|
--- Sends a USBpacket to the device
|
||||||
-- @param command - the usb packet to send
|
-- @param command - the usb packet to send
|
||||||
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
||||||
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
||||||
-- response of type CMD_ACK
|
-- response of type CMD_ACK
|
||||||
-- @return packet,nil if successfull
|
-- @return packet,nil if successfull
|
||||||
-- nil, errormessage if unsuccessfull
|
-- nil, errormessage if unsuccessfull
|
||||||
local function sendToDevice(command, ignoreresponse)
|
local function sendToDevice(command, ignoreresponse)
|
||||||
--core.clearCommandBuffer()
|
--core.clearCommandBuffer()
|
||||||
local err = core.SendCommand(command:getBytes())
|
local err = core.SendCommand(command:getBytes())
|
||||||
if err then
|
if err then
|
||||||
print(err)
|
print(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
if ignoreresponse then return nil,nil end
|
if ignoreresponse then return nil,nil end
|
||||||
|
|
||||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
||||||
return response,nil
|
return response,nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This function does a connect and retrieves som einfo
|
-- This function does a connect and retrieves som einfo
|
||||||
|
@ -96,34 +96,34 @@ end
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successfull: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function read14443a(dont_disconnect, no_rats)
|
local function read14443a(dont_disconnect, no_rats)
|
||||||
local command, result, info, err, data
|
local command, result, info, err, data
|
||||||
|
|
||||||
command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = ISO14A_COMMAND.ISO14A_CONNECT }
|
command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = ISO14A_COMMAND.ISO14A_CONNECT }
|
||||||
|
|
||||||
if dont_disconnect then
|
if dont_disconnect then
|
||||||
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
||||||
end
|
end
|
||||||
if no_rats then
|
if no_rats then
|
||||||
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS
|
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS
|
||||||
end
|
end
|
||||||
|
|
||||||
local result,err = sendToDevice(command)
|
|
||||||
if result then
|
|
||||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
|
||||||
if arg0 == 0 then
|
|
||||||
return nil, "iso14443a card select failed"
|
|
||||||
end
|
|
||||||
data = string.sub(result,count)
|
|
||||||
info, err = parse14443a(data)
|
|
||||||
else
|
|
||||||
err ="No response from card"
|
|
||||||
end
|
|
||||||
|
|
||||||
if err then
|
local result,err = sendToDevice(command)
|
||||||
print(err)
|
if result then
|
||||||
return nil, err
|
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
||||||
end
|
if arg0 == 0 then
|
||||||
return info
|
return nil, "iso14443a card select failed"
|
||||||
|
end
|
||||||
|
data = string.sub(result,count)
|
||||||
|
info, err = parse14443a(data)
|
||||||
|
else
|
||||||
|
err ="No response from card"
|
||||||
|
end
|
||||||
|
|
||||||
|
if err then
|
||||||
|
print(err)
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
return info
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -131,20 +131,20 @@ end
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successfull: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function waitFor14443a()
|
local function waitFor14443a()
|
||||||
print("Waiting for card... press any key to quit")
|
print("Waiting for card... press any key to quit")
|
||||||
while not core.ukbhit() do
|
while not core.ukbhit() do
|
||||||
res, err = read14443a()
|
res, err = read14443a()
|
||||||
if res then return res end
|
if res then return res end
|
||||||
-- err means that there was no response from card
|
-- err means that there was no response from card
|
||||||
end
|
end
|
||||||
return nil, "Aborted by user"
|
return nil, "Aborted by user"
|
||||||
end
|
end
|
||||||
local library = {
|
local library = {
|
||||||
read = read14443a,
|
read = read14443a,
|
||||||
waitFor14443a = waitFor14443a,
|
waitFor14443a = waitFor14443a,
|
||||||
parse14443a = parse14443a,
|
parse14443a = parse14443a,
|
||||||
sendToDevice = sendToDevice,
|
sendToDevice = sendToDevice,
|
||||||
ISO14A_COMMAND = ISO14A_COMMAND,
|
ISO14A_COMMAND = ISO14A_COMMAND,
|
||||||
}
|
}
|
||||||
|
|
||||||
return library
|
return library
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
--[[
|
--[[
|
||||||
This is a library to read 14443b tags. It can be used something like this
|
This is a library to read 14443b tags. It can be used something like this
|
||||||
|
|
||||||
local reader = require('read14b')
|
local reader = require('read14b')
|
||||||
result, err = reader.select1443b()
|
result, err = reader.select1443b()
|
||||||
if not result then
|
if not result then
|
||||||
print(err)
|
print(err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
print(result.name)
|
print(result.name)
|
||||||
|
|
||||||
--]]
|
--]]
|
||||||
-- Loads the commands-library
|
-- Loads the commands-library
|
||||||
|
@ -15,68 +15,68 @@ local cmds = require('commands')
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local TIMEOUT = 2500
|
local TIMEOUT = 2500
|
||||||
local ISO14B_COMMAND = {
|
local ISO14B_COMMAND = {
|
||||||
ISO14B_CONNECT = 1,
|
ISO14B_CONNECT = 1,
|
||||||
ISO14B_DISCONNECT = 2,
|
ISO14B_DISCONNECT = 2,
|
||||||
ISO14B_APDU = 4,
|
ISO14B_APDU = 4,
|
||||||
ISO14B_RAW = 8,
|
ISO14B_RAW = 8,
|
||||||
ISO14B_REQUEST_TRIGGER = 0x10,
|
ISO14B_REQUEST_TRIGGER = 0x10,
|
||||||
ISO14B_APPEND_CRC = 0x20,
|
ISO14B_APPEND_CRC = 0x20,
|
||||||
ISO14B_SELECT_STD = 0x40,
|
ISO14B_SELECT_STD = 0x40,
|
||||||
ISO14B_SELECT_SR = 0x80,
|
ISO14B_SELECT_SR = 0x80,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function parse1443b(data)
|
local function parse1443b(data)
|
||||||
--[[
|
--[[
|
||||||
|
|
||||||
Based on this struct :
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
byte_t uid[10];
|
|
||||||
byte_t uidlen;
|
|
||||||
byte_t atqb[7];
|
|
||||||
byte_t chipid;
|
|
||||||
byte_t cid;
|
|
||||||
} __attribute__((__packed__)) iso14b_card_select_t;
|
|
||||||
|
|
||||||
--]]
|
Based on this struct :
|
||||||
|
|
||||||
local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
|
typedef struct {
|
||||||
uid = uid:sub(1, 2*uidlen)
|
byte_t uid[10];
|
||||||
return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
|
byte_t uidlen;
|
||||||
|
byte_t atqb[7];
|
||||||
|
byte_t chipid;
|
||||||
|
byte_t cid;
|
||||||
|
} __attribute__((__packed__)) iso14b_card_select_t;
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
|
||||||
|
uid = uid:sub(1, 2*uidlen)
|
||||||
|
return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sends a USBpacket to the device
|
--- Sends a USBpacket to the device
|
||||||
-- @param command - the usb packet to send
|
-- @param command - the usb packet to send
|
||||||
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
||||||
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
||||||
-- response of type CMD_ACK
|
-- response of type CMD_ACK
|
||||||
-- @return packet,nil if successfull
|
-- @return packet,nil if successfull
|
||||||
-- nil, errormessage if unsuccessfull
|
-- nil, errormessage if unsuccessfull
|
||||||
local function sendToDevice(cmd, ignoreresponse)
|
local function sendToDevice(cmd, ignoreresponse)
|
||||||
--core.clearCommandBuffer()
|
--core.clearCommandBuffer()
|
||||||
local bytes = cmd:getBytes()
|
local bytes = cmd:getBytes()
|
||||||
local count,c,arg0,arg1,arg2 = bin.unpack('LLLL',bytes)
|
local count,c,arg0,arg1,arg2 = bin.unpack('LLLL',bytes)
|
||||||
local err = core.SendCommand(cmd:getBytes())
|
local err = core.SendCommand(cmd:getBytes())
|
||||||
if err then
|
if err then
|
||||||
print('ERROR',err)
|
print('ERROR',err)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
if ignoreresponse then return nil,nil end
|
if ignoreresponse then return nil,nil end
|
||||||
|
|
||||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
||||||
return response,nil
|
return response,nil
|
||||||
end
|
end
|
||||||
--- Picks out and displays the data read from a tag
|
--- Picks out and displays the data read from a tag
|
||||||
-- Specifically, takes a usb packet, converts to a Command
|
-- Specifically, takes a usb packet, converts to a Command
|
||||||
-- (as in commands.lua), takes the data-array and
|
-- (as in commands.lua), takes the data-array and
|
||||||
-- reads the number of bytes specified in arg1 (arg0 in c-struct)
|
-- reads the number of bytes specified in arg1 (arg0 in c-struct)
|
||||||
-- and displays the data
|
-- and displays the data
|
||||||
-- @param usbpacket the data received from the device
|
-- @param usbpacket the data received from the device
|
||||||
local function showData(usbpacket)
|
local function showData(usbpacket)
|
||||||
local response = Command.parse(usbpacket)
|
local response = Command.parse(usbpacket)
|
||||||
local len = response.arg2 * 2
|
local len = response.arg2 * 2
|
||||||
local data = string.sub(response.data, 0, len);
|
local data = string.sub(response.data, 0, len);
|
||||||
print("<< ",data)
|
print("<< ",data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,74 +85,74 @@ end
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function read14443b(disconnect)
|
local function read14443b(disconnect)
|
||||||
|
|
||||||
local command, result, info, err, data
|
local command, result, info, err, data
|
||||||
|
|
||||||
local flags = ISO14B_COMMAND.ISO14B_CONNECT +
|
local flags = ISO14B_COMMAND.ISO14B_CONNECT +
|
||||||
ISO14B_COMMAND.ISO14B_SELECT_STD
|
ISO14B_COMMAND.ISO14B_SELECT_STD
|
||||||
|
|
||||||
if disconnect then
|
|
||||||
print('DISCONNECT')
|
|
||||||
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
|
|
||||||
end
|
|
||||||
|
|
||||||
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
if disconnect then
|
||||||
local result, err = sendToDevice(command, false)
|
print('DISCONNECT')
|
||||||
if result then
|
flags = flags + ISO14B_COMMAND.ISO14B_DISCONNECT
|
||||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
end
|
||||||
if arg0 == 0 then
|
|
||||||
data = string.sub(result, count)
|
|
||||||
info, err = parse1443b(data)
|
|
||||||
else
|
|
||||||
err = "iso14443b card select failed"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
err = "No response from card"
|
|
||||||
end
|
|
||||||
|
|
||||||
if err then
|
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
|
||||||
print(err)
|
local result, err = sendToDevice(command, false)
|
||||||
return nil, err
|
if result then
|
||||||
end
|
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
||||||
return info
|
if arg0 == 0 then
|
||||||
|
data = string.sub(result, count)
|
||||||
|
info, err = parse1443b(data)
|
||||||
|
else
|
||||||
|
err = "iso14443b card select failed"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
err = "No response from card"
|
||||||
|
end
|
||||||
|
|
||||||
|
if err then
|
||||||
|
print(err)
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
return info
|
||||||
end
|
end
|
||||||
--PING / PONG - Custom Anticollison for Navigo.
|
--PING / PONG - Custom Anticollison for Navigo.
|
||||||
-- AA / BB ?!?
|
-- AA / BB ?!?
|
||||||
-- local ping = ('BA00')
|
-- local ping = ('BA00')
|
||||||
-- result, err = sendRaw(ping, 1, 1)
|
-- result, err = sendRaw(ping, 1, 1)
|
||||||
-- if result then
|
-- if result then
|
||||||
-- resp = Command.parse( result )
|
-- resp = Command.parse( result )
|
||||||
-- if arg1 == 0 then
|
-- if arg1 == 0 then
|
||||||
-- return nil, "iso14443b card - PING/PONG failed"
|
-- return nil, "iso14443b card - PING/PONG failed"
|
||||||
-- end
|
-- end
|
||||||
-- showData(result)
|
-- showData(result)
|
||||||
-- else
|
-- else
|
||||||
-- err = "No response from card"
|
-- err = "No response from card"
|
||||||
-- print(err)
|
-- print(err)
|
||||||
-- return nil, err
|
-- return nil, err
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
-- Waits for a mifare card to be placed within the vicinity of the reader.
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successfull: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function waitFor14443b()
|
local function waitFor14443b()
|
||||||
print("Waiting for card... press any key to quit")
|
print("Waiting for card... press any key to quit")
|
||||||
while not core.ukbhit() do
|
while not core.ukbhit() do
|
||||||
res, err = read14443b(false)
|
res, err = read14443b(false)
|
||||||
if res then return res end
|
if res then return res end
|
||||||
-- err means that there was no response from card
|
-- err means that there was no response from card
|
||||||
end
|
end
|
||||||
return nil, "Aborted by user"
|
return nil, "Aborted by user"
|
||||||
end
|
end
|
||||||
|
|
||||||
local library = {
|
local library = {
|
||||||
read = read14443b,
|
read = read14443b,
|
||||||
waitFor14443b = waitFor14443b,
|
waitFor14443b = waitFor14443b,
|
||||||
parse1443b = parse1443b,
|
parse1443b = parse1443b,
|
||||||
sendToDevice = sendToDevice,
|
sendToDevice = sendToDevice,
|
||||||
showData = showData,
|
showData = showData,
|
||||||
ISO14B_COMMAND = ISO14B_COMMAND,
|
ISO14B_COMMAND = ISO14B_COMMAND,
|
||||||
}
|
}
|
||||||
|
|
||||||
return library
|
return library
|
|
@ -1,13 +1,13 @@
|
||||||
--[[
|
--[[
|
||||||
This is a library to read 15693 tags. It can be used something like this
|
This is a library to read 15693 tags. It can be used something like this
|
||||||
|
|
||||||
local reader = require('read15')
|
local reader = require('read15')
|
||||||
local info, err = reader.read()
|
local info, err = reader.read()
|
||||||
if not info then
|
if not info then
|
||||||
print(err)
|
print(err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
print(info.UID)
|
print(info.UID)
|
||||||
|
|
||||||
--]]
|
--]]
|
||||||
-- Loads the commands-library
|
-- Loads the commands-library
|
||||||
|
@ -19,60 +19,60 @@ local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||||
--- Sends a USBpacket to the device
|
--- Sends a USBpacket to the device
|
||||||
-- @param command - the usb packet to send
|
-- @param command - the usb packet to send
|
||||||
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
||||||
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
||||||
-- response of type CMD_ACK
|
-- response of type CMD_ACK
|
||||||
-- @return packet,nil if successfull
|
-- @return packet,nil if successfull
|
||||||
-- nil, errormessage if unsuccessfull
|
-- nil, errormessage if unsuccessfull
|
||||||
local function sendToDevice(command, ignoreresponse)
|
local function sendToDevice(command, ignoreresponse)
|
||||||
local err = core.SendCommand(command:getBytes())
|
local err = core.SendCommand(command:getBytes())
|
||||||
if err then
|
if err then
|
||||||
print(err)
|
print(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
if ignoreresponse then return nil, nil end
|
if ignoreresponse then return nil, nil end
|
||||||
|
|
||||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
|
||||||
return response, nil
|
return response, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local function errorString15693(number)
|
local function errorString15693(number)
|
||||||
local errors = {}
|
local errors = {}
|
||||||
errors[0x01] = "The command is not supported"
|
errors[0x01] = "The command is not supported"
|
||||||
errors[0x02] = "The command is not recognised"
|
errors[0x02] = "The command is not recognised"
|
||||||
errors[0x03] = "The option is not supported."
|
errors[0x03] = "The option is not supported."
|
||||||
errors[0x0f] = "Unknown error."
|
errors[0x0f] = "Unknown error."
|
||||||
errors[0x10] = "The specified block is not available (doesn’t exist)."
|
errors[0x10] = "The specified block is not available (doesn’t exist)."
|
||||||
errors[0x11] = "The specified block is already -locked and thus cannot be locked again"
|
errors[0x11] = "The specified block is already -locked and thus cannot be locked again"
|
||||||
errors[0x12] = "The specified block is locked and its content cannot be changed."
|
errors[0x12] = "The specified block is locked and its content cannot be changed."
|
||||||
errors[0x13] = "The specified block was not successfully programmed."
|
errors[0x13] = "The specified block was not successfully programmed."
|
||||||
errors[0x14] = "The specified block was not successfully locked."
|
errors[0x14] = "The specified block was not successfully locked."
|
||||||
|
|
||||||
return errors[number] or "Reserved for Future Use or Custom command error."
|
return errors[number] or "Reserved for Future Use or Custom command error."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function parse15693(data)
|
local function parse15693(data)
|
||||||
local bytes = utils.ConvertAsciiToBytes(data)
|
local bytes = utils.ConvertAsciiToBytes(data)
|
||||||
local tmp = utils.ConvertAsciiToHex(data)
|
local tmp = utils.ConvertAsciiToHex(data)
|
||||||
|
|
||||||
-- define ISO15_CRC_CHECK 0F47
|
|
||||||
local crcStr = utils.Crc15(tmp, #tmp)
|
|
||||||
|
|
||||||
if string.sub(crcStr, #crcStr - 3) ~= '470F' then
|
-- define ISO15_CRC_CHECK 0F47
|
||||||
print("CRC", crc )
|
local crcStr = utils.Crc15(tmp, #tmp)
|
||||||
return nil, "CRC failed"
|
|
||||||
end
|
|
||||||
|
|
||||||
if bytes[1] % 2 == 1 then
|
if string.sub(crcStr, #crcStr - 3) ~= '470F' then
|
||||||
-- Above is a poor-mans bit check:
|
print("CRC", crc )
|
||||||
-- recv[0] & ISO15_RES_ERROR //(0x01)
|
return nil, "CRC failed"
|
||||||
local err = "Tag returned error %i: %s"
|
end
|
||||||
err = string.format(err, bytes[1], errorString15693(bytes[1]))
|
|
||||||
return nil, err
|
if bytes[1] % 2 == 1 then
|
||||||
end
|
-- Above is a poor-mans bit check:
|
||||||
local uid = utils.ConvertBytesToHex( bytes, true )
|
-- recv[0] & ISO15_RES_ERROR //(0x01)
|
||||||
uid = uid:sub(5, #uid-4)
|
local err = "Tag returned error %i: %s"
|
||||||
return { uid = uid, }
|
err = string.format(err, bytes[1], errorString15693(bytes[1]))
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
local uid = utils.ConvertBytesToHex( bytes, true )
|
||||||
|
uid = uid:sub(5, #uid-4)
|
||||||
|
return { uid = uid, }
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This function does a connect and retrieves som info
|
-- This function does a connect and retrieves som info
|
||||||
|
@ -83,62 +83,62 @@ local function read15693(slow, dont_readresponse)
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
|
||||||
We start by trying this command:
|
We start by trying this command:
|
||||||
MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
|
MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
|
||||||
|
|
||||||
pm3> hf 15 info u
|
|
||||||
UID=E007C1A257394244
|
|
||||||
Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
|
|
||||||
pm3>
|
|
||||||
|
|
||||||
From which we obtain less information than the above one.
|
|
||||||
|
|
||||||
"260100" means
|
|
||||||
0x26
|
|
||||||
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
|
||||||
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
|
|
||||||
-- #define ISO15_REQ_NONINVENTORY 0x00
|
|
||||||
0x01
|
|
||||||
inventory
|
|
||||||
0x00
|
|
||||||
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local command, result, info, err, data
|
pm3> hf 15 info u
|
||||||
|
UID=E007C1A257394244
|
||||||
|
Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
|
||||||
|
pm3>
|
||||||
|
|
||||||
data = utils.Crc15("260100")
|
From which we obtain less information than the above one.
|
||||||
|
|
||||||
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
|
"260100" means
|
||||||
arg1 = #data / 2,
|
0x26
|
||||||
arg2 = 1,
|
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
||||||
arg3 = 1,
|
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
|
||||||
data = data}
|
-- #define ISO15_REQ_NONINVENTORY 0x00
|
||||||
|
0x01
|
||||||
if slow then
|
inventory
|
||||||
command.arg2 = 0
|
0x00
|
||||||
end
|
|
||||||
if dont_readresponse then
|
--]]
|
||||||
command.arg3 = 0
|
|
||||||
end
|
local command, result, info, err, data
|
||||||
|
|
||||||
local result, err = sendToDevice(command, dont_readresponse)
|
data = utils.Crc15("260100")
|
||||||
if not result then
|
|
||||||
print(err)
|
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
|
||||||
return nil, "15693 identify: no answer"
|
arg1 = #data / 2,
|
||||||
end
|
arg2 = 1,
|
||||||
|
arg3 = 1,
|
||||||
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
|
data = data}
|
||||||
if len > 0 then
|
|
||||||
data = string.sub(result, count, count+len-1)
|
if slow then
|
||||||
info, err = parse15693(data)
|
command.arg2 = 0
|
||||||
if err then
|
end
|
||||||
print(err)
|
if dont_readresponse then
|
||||||
return nil, err
|
command.arg3 = 0
|
||||||
end
|
end
|
||||||
return info
|
|
||||||
else
|
local result, err = sendToDevice(command, dont_readresponse)
|
||||||
return nil, "Failed to get response"
|
if not result then
|
||||||
end
|
print(err)
|
||||||
|
return nil, "15693 identify: no answer"
|
||||||
|
end
|
||||||
|
|
||||||
|
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
|
||||||
|
if len > 0 then
|
||||||
|
data = string.sub(result, count, count+len-1)
|
||||||
|
info, err = parse15693(data)
|
||||||
|
if err then
|
||||||
|
print(err)
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
return info
|
||||||
|
else
|
||||||
|
return nil, "Failed to get response"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -146,19 +146,19 @@ end
|
||||||
-- @return if successfull: an table containing card info
|
-- @return if successfull: an table containing card info
|
||||||
-- @return if unsuccessfull : nil, error
|
-- @return if unsuccessfull : nil, error
|
||||||
local function waitFor15693()
|
local function waitFor15693()
|
||||||
print("Waiting for card... press any key to quit")
|
print("Waiting for card... press any key to quit")
|
||||||
while not core.ukbhit() do
|
while not core.ukbhit() do
|
||||||
res, err = read15693()
|
res, err = read15693()
|
||||||
if res then return res end
|
if res then return res end
|
||||||
-- err means that there was no response from card
|
-- err means that there was no response from card
|
||||||
end
|
end
|
||||||
return nil, "Aborted by user"
|
return nil, "Aborted by user"
|
||||||
end
|
end
|
||||||
local library = {
|
local library = {
|
||||||
read = read15693,
|
read = read15693,
|
||||||
waitFor15693 = waitFor15693,
|
waitFor15693 = waitFor15693,
|
||||||
parse15693 = parse15693,
|
parse15693 = parse15693,
|
||||||
sendToDevice = sendToDevice,
|
sendToDevice = sendToDevice,
|
||||||
}
|
}
|
||||||
|
|
||||||
return library
|
return library
|
||||||
|
|
|
@ -109,16 +109,16 @@ m[0x6B]='ISSM France'
|
||||||
m[0x6C]='Wisesec Ltd Israel'
|
m[0x6C]='Wisesec Ltd Israel'
|
||||||
m[0x7C]='DB HiTek Co Ltd Korea'
|
m[0x7C]='DB HiTek Co Ltd Korea'
|
||||||
m[0x7D]='SATO Vicinity Australia'
|
m[0x7D]='SATO Vicinity Australia'
|
||||||
m[0x7E]='Holtek Taiwan'
|
m[0x7E]='Holtek Taiwan'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
lookupManufacturer = function (value)
|
lookupManufacturer = function (value)
|
||||||
if type(value) == 'string' then
|
if type(value) == 'string' then
|
||||||
local v = tonumber(value, 16)
|
local v = tonumber(value, 16)
|
||||||
print(string.format("WARNING: lookupManufacturer expects numeric value, converted %s into %x", value,v))
|
print(string.format("WARNING: lookupManufacturer expects numeric value, converted %s into %x", value,v))
|
||||||
value = v
|
value = v
|
||||||
end
|
end
|
||||||
|
|
||||||
return m[value] or "no tag-info available"
|
return m[value] or "no tag-info available"
|
||||||
end,
|
end,
|
||||||
}
|
}
|
|
@ -1,430 +1,430 @@
|
||||||
--[[
|
--[[
|
||||||
This may be moved to a separate library at some point (Holiman)
|
This may be moved to a separate library at some point (Holiman)
|
||||||
--]]
|
--]]
|
||||||
local Utils =
|
local Utils =
|
||||||
{
|
{
|
||||||
-- Asks the user for Yes or No
|
-- Asks the user for Yes or No
|
||||||
confirm = function(message, ...)
|
confirm = function(message, ...)
|
||||||
local answer
|
local answer
|
||||||
message = message .. " [y/n] ?"
|
message = message .. " [y/n] ?"
|
||||||
repeat
|
repeat
|
||||||
io.write(message)
|
io.write(message)
|
||||||
io.flush()
|
io.flush()
|
||||||
answer = io.read()
|
answer = io.read()
|
||||||
if answer == 'Y' or answer == "y" then
|
if answer == 'Y' or answer == "y" then
|
||||||
return true
|
return true
|
||||||
elseif answer == 'N' or answer == 'n' then
|
elseif answer == 'N' or answer == 'n' then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
until false
|
until false
|
||||||
end,
|
end,
|
||||||
---
|
---
|
||||||
-- Asks the user for input
|
-- Asks the user for input
|
||||||
input = function (message , default)
|
input = function (message , default)
|
||||||
local answer
|
local answer
|
||||||
if default ~= nil then
|
if default ~= nil then
|
||||||
message = message .. " (default: ".. default.. " )"
|
message = message .. " (default: ".. default.. " )"
|
||||||
end
|
end
|
||||||
message = message .." \n > "
|
message = message .." \n > "
|
||||||
io.write(message)
|
io.write(message)
|
||||||
io.flush()
|
io.flush()
|
||||||
answer = io.read()
|
answer = io.read()
|
||||||
if answer == '' then answer = default end
|
if answer == '' then answer = default end
|
||||||
|
|
||||||
return answer
|
return answer
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ FILE READING
|
------------ FILE READING
|
||||||
ReadDumpFile = function (filename)
|
ReadDumpFile = function (filename)
|
||||||
|
|
||||||
filename = filename or 'dumpdata.bin'
|
filename = filename or 'dumpdata.bin'
|
||||||
if #filename == 0 then
|
if #filename == 0 then
|
||||||
return nil, 'Filename length is zero'
|
return nil, 'Filename length is zero'
|
||||||
end
|
end
|
||||||
|
|
||||||
infile = io.open(filename, "rb")
|
infile = io.open(filename, "rb")
|
||||||
if infile == nil then
|
if infile == nil then
|
||||||
return nil, string.format("Could not read file %s",filename)
|
return nil, string.format("Could not read file %s",filename)
|
||||||
end
|
end
|
||||||
local t = infile:read("*all")
|
local t = infile:read("*all")
|
||||||
io.close(infile)
|
io.close(infile)
|
||||||
len = string.len(t)
|
len = string.len(t)
|
||||||
local _,hex = bin.unpack(("H%d"):format(len),t)
|
local _,hex = bin.unpack(("H%d"):format(len),t)
|
||||||
return hex
|
return hex
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ FILE WRITING (EML)
|
------------ FILE WRITING (EML)
|
||||||
--- Writes an eml-file.
|
--- Writes an eml-file.
|
||||||
-- @param uid - the uid of the tag. Used in filename
|
-- @param uid - the uid of the tag. Used in filename
|
||||||
-- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ...,
|
-- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ...,
|
||||||
-- that is, blockData[row] contains a string with the actual data, not ascii hex representation
|
-- that is, blockData[row] contains a string with the actual data, not ascii hex representation
|
||||||
-- return filename if all went well,
|
-- return filename if all went well,
|
||||||
-- @reurn nil, error message if unsuccessfulls
|
-- @reurn nil, error message if unsuccessfulls
|
||||||
WriteDumpFile = function(uid, blockData)
|
WriteDumpFile = function(uid, blockData)
|
||||||
local destination = string.format("%s.eml", uid)
|
local destination = string.format("%s.eml", uid)
|
||||||
local file = io.open(destination, "w")
|
local file = io.open(destination, "w")
|
||||||
if file == nil then
|
if file == nil then
|
||||||
return nil, string.format("Could not write to file %s", destination)
|
return nil, string.format("Could not write to file %s", destination)
|
||||||
end
|
end
|
||||||
local rowlen = string.len(blockData[1])
|
local rowlen = string.len(blockData[1])
|
||||||
|
|
||||||
for i,block in ipairs(blockData) do
|
for i,block in ipairs(blockData) do
|
||||||
if rowlen ~= string.len(block) then
|
if rowlen ~= string.len(block) then
|
||||||
prlog(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i))
|
prlog(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i))
|
||||||
end
|
end
|
||||||
|
|
||||||
local formatString = string.format("H%d", string.len(block))
|
local formatString = string.format("H%d", string.len(block))
|
||||||
local _,hex = bin.unpack(formatString,block)
|
local _,hex = bin.unpack(formatString,block)
|
||||||
file:write(hex.."\n")
|
file:write(hex.."\n")
|
||||||
end
|
end
|
||||||
file:close()
|
file:close()
|
||||||
return destination
|
return destination
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ string split function
|
------------ string split function
|
||||||
Split = function( inSplitPattern, outResults )
|
Split = function( inSplitPattern, outResults )
|
||||||
if not outResults then
|
if not outResults then
|
||||||
outResults = {}
|
outResults = {}
|
||||||
end
|
end
|
||||||
local start = 1
|
local start = 1
|
||||||
local splitStart, splitEnd = string.find( self, inSplitPattern, start )
|
local splitStart, splitEnd = string.find( self, inSplitPattern, start )
|
||||||
while splitStart do
|
while splitStart do
|
||||||
table.insert( outResults, string.sub( self, start, splitStart-1 ) )
|
table.insert( outResults, string.sub( self, start, splitStart-1 ) )
|
||||||
start = splitEnd + 1
|
start = splitEnd + 1
|
||||||
splitStart, splitEnd = string.find( self, inSplitPattern, start )
|
splitStart, splitEnd = string.find( self, inSplitPattern, start )
|
||||||
end
|
end
|
||||||
table.insert( outResults, string.sub( self, start ) )
|
table.insert( outResults, string.sub( self, start ) )
|
||||||
return outResults
|
return outResults
|
||||||
end,
|
end,
|
||||||
|
|
||||||
----ISO14443-B CRC
|
----ISO14443-B CRC
|
||||||
Crc14b = function(s)
|
Crc14b = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
return utils.ConvertAsciiToHex(
|
return utils.ConvertAsciiToHex(
|
||||||
core.iso14443b_crc(s)
|
core.iso14443b_crc(s)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
----ISO15693 CRC
|
----ISO15693 CRC
|
||||||
Crc15 = function(s)
|
Crc15 = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
return utils.ConvertAsciiToHex(
|
return utils.ConvertAsciiToHex(
|
||||||
core.iso15693_crc(s)
|
core.iso15693_crc(s)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ CRC-8 Legic checksums
|
------------ CRC-8 Legic checksums
|
||||||
-- Takes a hex string and calculates a crc8
|
-- Takes a hex string and calculates a crc8
|
||||||
Crc8Legic = function(s)
|
Crc8Legic = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local asc = utils.ConvertHexToAscii(s)
|
local asc = utils.ConvertHexToAscii(s)
|
||||||
local hash = core.crc8legic(asc)
|
local hash = core.crc8legic(asc)
|
||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ CRC-16 ccitt checksums
|
------------ CRC-16 ccitt checksums
|
||||||
-- Takes a hex string and calculates a crc16
|
-- Takes a hex string and calculates a crc16
|
||||||
Crc16 = function(s)
|
Crc16 = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local asc = utils.ConvertHexToAscii(s)
|
local asc = utils.ConvertHexToAscii(s)
|
||||||
local hash = core.crc16(asc)
|
local hash = core.crc16(asc)
|
||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
||||||
------------ CRC-64 ecma checksums
|
------------ CRC-64 ecma checksums
|
||||||
-- Takes a hex string and calculates a crc64 ecma hash
|
-- Takes a hex string and calculates a crc64 ecma hash
|
||||||
Crc64 = function(s)
|
Crc64 = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local asc = utils.ConvertHexToAscii(s)
|
local asc = utils.ConvertHexToAscii(s)
|
||||||
local hash = core.crc64(asc)
|
local hash = core.crc64(asc)
|
||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
------------ CRC-64 ecma 182 checksums
|
------------ CRC-64 ecma 182 checksums
|
||||||
-- Takes a hex string and calculates a crc64 ecma182 hash
|
-- Takes a hex string and calculates a crc64 ecma182 hash
|
||||||
Crc64_ecma182 = function(s)
|
Crc64_ecma182 = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local asc = utils.ConvertHexToAscii(s)
|
local asc = utils.ConvertHexToAscii(s)
|
||||||
local hash = core.crc64_ecma182(asc)
|
local hash = core.crc64_ecma182(asc)
|
||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
------------ SHA1 hash
|
------------ SHA1 hash
|
||||||
-- Takes a string and calculates a SHA1 hash
|
-- Takes a string and calculates a SHA1 hash
|
||||||
Sha1 = function(s)
|
Sha1 = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
return core.sha1(s)
|
return core.sha1(s)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
-- Takes a hex string and calculates a SHA1 hash
|
-- Takes a hex string and calculates a SHA1 hash
|
||||||
Sha1Hex = function(s)
|
Sha1Hex = function(s)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return nil end
|
if #s == 0 then return nil end
|
||||||
if type(s) == 'string' then
|
if type(s) == 'string' then
|
||||||
local utils = require('utils')
|
local utils = require('utils')
|
||||||
local asc = utils.ConvertHexToAscii(s)
|
local asc = utils.ConvertHexToAscii(s)
|
||||||
local hash = core.sha1(asc)
|
local hash = core.sha1(asc)
|
||||||
return hash
|
return hash
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
||||||
-- input parameter is a string
|
-- input parameter is a string
|
||||||
-- Swaps the endianess and returns a number,
|
-- Swaps the endianess and returns a number,
|
||||||
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
||||||
SwapEndianness = function(s, len)
|
SwapEndianness = function(s, len)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return '' end
|
if #s == 0 then return '' end
|
||||||
if type(s) ~= 'string' then return nil end
|
if type(s) ~= 'string' then return nil end
|
||||||
|
|
||||||
local retval = 0
|
local retval = 0
|
||||||
if len == 16 then
|
if len == 16 then
|
||||||
local t = s:sub(3,4)..s:sub(1,2)
|
local t = s:sub(3,4)..s:sub(1,2)
|
||||||
retval = tonumber(t,16)
|
retval = tonumber(t,16)
|
||||||
elseif len == 24 then
|
elseif len == 24 then
|
||||||
local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
retval = tonumber(t,16)
|
retval = tonumber(t,16)
|
||||||
elseif len == 32 then
|
elseif len == 32 then
|
||||||
local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
retval = tonumber(t,16)
|
retval = tonumber(t,16)
|
||||||
end
|
end
|
||||||
return retval
|
return retval
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- input parameter is a string
|
-- input parameter is a string
|
||||||
-- Swaps the endianess and returns a string,
|
-- Swaps the endianess and returns a string,
|
||||||
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
||||||
SwapEndiannessStr = function(s, len)
|
SwapEndiannessStr = function(s, len)
|
||||||
if s == nil then return nil end
|
if s == nil then return nil end
|
||||||
if #s == 0 then return '' end
|
if #s == 0 then return '' end
|
||||||
if type(s) ~= 'string' then return nil end
|
if type(s) ~= 'string' then return nil end
|
||||||
|
|
||||||
local retval
|
local retval
|
||||||
if len == 16 then
|
if len == 16 then
|
||||||
retval = s:sub(3,4)..s:sub(1,2)
|
retval = s:sub(3,4)..s:sub(1,2)
|
||||||
elseif len == 24 then
|
elseif len == 24 then
|
||||||
retval = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
retval = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
elseif len == 32 then
|
elseif len == 32 then
|
||||||
retval = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
retval = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
end
|
end
|
||||||
return retval
|
return retval
|
||||||
end,
|
end,
|
||||||
------------ CONVERSIONS
|
------------ CONVERSIONS
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Converts DECIMAL to HEX
|
-- Converts DECIMAL to HEX
|
||||||
ConvertDecToHex = function(IN)
|
ConvertDecToHex = function(IN)
|
||||||
local B,K,OUT,I,D = 16, "0123456789ABCDEF", "", 0
|
local B,K,OUT,I,D = 16, "0123456789ABCDEF", "", 0
|
||||||
while IN > 0 do
|
while IN > 0 do
|
||||||
I = I+1
|
I = I+1
|
||||||
IN, D = math.floor(IN/B), math.modf(IN, B) + 1
|
IN, D = math.floor(IN/B), math.modf(IN, B) + 1
|
||||||
OUT = string.sub(K, D, D)..OUT
|
OUT = string.sub(K, D, D)..OUT
|
||||||
end
|
end
|
||||||
return OUT
|
return OUT
|
||||||
end,
|
end,
|
||||||
---
|
---
|
||||||
-- Convert Byte array to string of hex
|
-- Convert Byte array to string of hex
|
||||||
ConvertBytesToHex = function(bytes, reverse)
|
ConvertBytesToHex = function(bytes, reverse)
|
||||||
if bytes == nil then return '' end
|
if bytes == nil then return '' end
|
||||||
if #bytes == 0 then return '' end
|
if #bytes == 0 then return '' end
|
||||||
local s={}
|
local s={}
|
||||||
if reverse then
|
if reverse then
|
||||||
local j=1
|
local j=1
|
||||||
for i = #bytes, 1, -1 do
|
for i = #bytes, 1, -1 do
|
||||||
s[i] = string.format("%02X", bytes[j])
|
s[i] = string.format("%02X", bytes[j])
|
||||||
j = j + 1
|
j = j + 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for i = 1, #bytes do
|
for i = 1, #bytes do
|
||||||
s[i] = string.format("%02X", bytes[i])
|
s[i] = string.format("%02X", bytes[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return table.concat(s)
|
return table.concat(s)
|
||||||
end,
|
end,
|
||||||
-- Convert byte array to string with ascii
|
-- Convert byte array to string with ascii
|
||||||
ConvertBytesToAscii = function(bytes)
|
ConvertBytesToAscii = function(bytes)
|
||||||
if bytes == nil then return '' end
|
if bytes == nil then return '' end
|
||||||
if #bytes == 0 then return '' end
|
if #bytes == 0 then return '' end
|
||||||
local s={}
|
local s={}
|
||||||
for i = 1, #(bytes) do
|
for i = 1, #(bytes) do
|
||||||
s[i] = string.char(bytes[i])
|
s[i] = string.char(bytes[i])
|
||||||
end
|
end
|
||||||
return table.concat(s)
|
return table.concat(s)
|
||||||
end,
|
end,
|
||||||
ConvertHexToBytes = function(s)
|
ConvertHexToBytes = function(s)
|
||||||
local t={}
|
local t={}
|
||||||
if s == nil then return t end
|
if s == nil then return t end
|
||||||
if #s == 0 then return t end
|
if #s == 0 then return t end
|
||||||
for k in s:gmatch"(%x%x)" do
|
for k in s:gmatch"(%x%x)" do
|
||||||
table.insert(t,tonumber(k,16))
|
table.insert(t,tonumber(k,16))
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
end,
|
end,
|
||||||
ConvertAsciiToBytes = function(s, reverse)
|
ConvertAsciiToBytes = function(s, reverse)
|
||||||
local t = {}
|
local t = {}
|
||||||
if s == nil then return t end
|
if s == nil then return t end
|
||||||
if #s == 0 then return t end
|
if #s == 0 then return t end
|
||||||
|
|
||||||
for k in s:gmatch"(.)" do
|
for k in s:gmatch"(.)" do
|
||||||
table.insert(t, string.byte(k))
|
table.insert(t, string.byte(k))
|
||||||
end
|
end
|
||||||
|
|
||||||
if not reverse then
|
if not reverse then
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
local rev = {}
|
local rev = {}
|
||||||
if reverse then
|
if reverse then
|
||||||
for i = #t, 1,-1 do
|
for i = #t, 1,-1 do
|
||||||
table.insert(rev, t[i] )
|
table.insert(rev, t[i] )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return rev
|
return rev
|
||||||
end,
|
end,
|
||||||
|
|
||||||
ConvertHexToAscii = function(s, useSafechars)
|
ConvertHexToAscii = function(s, useSafechars)
|
||||||
if s == nil then return '' end
|
if s == nil then return '' end
|
||||||
if #s == 0 then return '' end
|
if #s == 0 then return '' end
|
||||||
local t={}
|
local t={}
|
||||||
for k in s:gmatch"(%x%x)" do
|
for k in s:gmatch"(%x%x)" do
|
||||||
|
|
||||||
local n = tonumber(k,16)
|
local n = tonumber(k,16)
|
||||||
local c
|
local c
|
||||||
if useSafechars and ( (n < 32) or (n == 127) ) then
|
if useSafechars and ( (n < 32) or (n == 127) ) then
|
||||||
c = '.';
|
c = '.';
|
||||||
else
|
else
|
||||||
c = string.char(n)
|
c = string.char(n)
|
||||||
end
|
end
|
||||||
table.insert(t,c)
|
table.insert(t,c)
|
||||||
end
|
end
|
||||||
return table.concat(t)
|
return table.concat(t)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
ConvertAsciiToHex = function(s)
|
ConvertAsciiToHex = function(s)
|
||||||
if s == nil then return '' end
|
if s == nil then return '' end
|
||||||
if #s == 0 then return '' end
|
if #s == 0 then return '' end
|
||||||
local t={}
|
local t={}
|
||||||
for k in s:gmatch"(.)" do
|
for k in s:gmatch"(.)" do
|
||||||
table.insert(t, string.format("%02X", string.byte(k)))
|
table.insert(t, string.format("%02X", string.byte(k)))
|
||||||
end
|
end
|
||||||
return table.concat(t)
|
return table.concat(t)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
hexlify = function(s)
|
hexlify = function(s)
|
||||||
local u = require('utils')
|
local u = require('utils')
|
||||||
return u.ConvertAsciiToHex(s)
|
return u.ConvertAsciiToHex(s)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
Chars2num = function(s)
|
Chars2num = function(s)
|
||||||
return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4))
|
return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- use length of string to determine 8,16,32,64 bits
|
-- use length of string to determine 8,16,32,64 bits
|
||||||
bytes_to_int = function(str,endian,signed)
|
bytes_to_int = function(str,endian,signed)
|
||||||
local t = {str:byte(1, -1)}
|
local t = {str:byte(1, -1)}
|
||||||
if endian == "big" then --reverse bytes
|
if endian == "big" then --reverse bytes
|
||||||
local tt = {}
|
local tt = {}
|
||||||
for k = 1, #t do
|
for k = 1, #t do
|
||||||
tt[#t-k+1] = t[k]
|
tt[#t-k+1] = t[k]
|
||||||
end
|
end
|
||||||
t = tt
|
t = tt
|
||||||
end
|
end
|
||||||
local n = 0
|
local n = 0
|
||||||
for k = 1, #t do
|
for k = 1, #t do
|
||||||
n = n + t[k] * 2^((k-1) * 8)
|
n = n + t[k] * 2^((k-1) * 8)
|
||||||
end
|
end
|
||||||
if signed then
|
if signed then
|
||||||
n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative.
|
n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative.
|
||||||
end
|
end
|
||||||
return n
|
return n
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- a simple implementation of a sleep command. Thanks to Mosci
|
-- a simple implementation of a sleep command. Thanks to Mosci
|
||||||
-- takes number of seconds to sleep
|
-- takes number of seconds to sleep
|
||||||
Sleep = function(n)
|
Sleep = function(n)
|
||||||
local clock = os.clock
|
local clock = os.clock
|
||||||
local t0 = clock()
|
local t0 = clock()
|
||||||
while clock() - t0 <= n do end
|
while clock() - t0 <= n do end
|
||||||
return nil
|
return nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- function convertStringToBytes(str)
|
-- function convertStringToBytes(str)
|
||||||
-- local bytes = {}
|
-- local bytes = {}
|
||||||
-- local strLength = string.len(str)
|
-- local strLength = string.len(str)
|
||||||
-- for i=1,strLength do
|
-- for i=1,strLength do
|
||||||
-- table.insert(bytes, string.byte(str, i))
|
-- table.insert(bytes, string.byte(str, i))
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- return bytes
|
-- return bytes
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- function convertBytesToString(bytes)
|
-- function convertBytesToString(bytes)
|
||||||
-- local bytesLength = table.getn(bytes)
|
-- local bytesLength = table.getn(bytes)
|
||||||
-- local str = ""
|
-- local str = ""
|
||||||
-- for i=1,bytesLength do
|
-- for i=1,bytesLength do
|
||||||
-- str = str .. string.char(bytes[i])
|
-- str = str .. string.char(bytes[i])
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- return str
|
-- return str
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- function convertHexStringToBytes(str)
|
-- function convertHexStringToBytes(str)
|
||||||
-- local bytes = {}
|
-- local bytes = {}
|
||||||
-- local strLength = string.len(str)
|
-- local strLength = string.len(str)
|
||||||
-- for k=2,strLength,2 do
|
-- for k=2,strLength,2 do
|
||||||
-- local hexString = "0x" .. string.sub(str, (k - 1), k)
|
-- local hexString = "0x" .. string.sub(str, (k - 1), k)
|
||||||
-- table.insert(bytes, hex.to_dec(hexString))
|
-- table.insert(bytes, hex.to_dec(hexString))
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- return bytes
|
-- return bytes
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- function convertBytesToHexString(bytes)
|
-- function convertBytesToHexString(bytes)
|
||||||
-- local str = ""
|
-- local str = ""
|
||||||
-- local bytesLength = table.getn(bytes)
|
-- local bytesLength = table.getn(bytes)
|
||||||
-- for i=1,bytesLength do
|
-- for i=1,bytesLength do
|
||||||
-- local hexString = string.sub(hex.to_hex(bytes[i]), 3)
|
-- local hexString = string.sub(hex.to_hex(bytes[i]), 3)
|
||||||
-- if string.len(hexString) == 1 then
|
-- if string.len(hexString) == 1 then
|
||||||
-- hexString = "0" .. hexString
|
-- hexString = "0" .. hexString
|
||||||
-- end
|
-- end
|
||||||
-- str = str .. hexString
|
-- str = str .. hexString
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- return str
|
-- return str
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
}
|
}
|
||||||
return Utils
|
return Utils
|
Loading…
Add table
Add a link
Reference in a new issue