2 This may be moved to a separate library at some point (Holiman)
6 -- Asks the user for Yes or No
7 confirm
= function(message
, ...)
9 message
= message
.. " [y/n] ?"
14 if answer
== 'Y' or answer
== "y" then
16 elseif answer
== 'N' or answer
== 'n' then
22 -- Asks the user for input
23 input
= function (message
, default
)
25 if default
~= nil then
26 message
= message
.. " (default: ".. default
.. " )"
28 io
.write(message
, "\n > ")
30 answer
= io
.read("*L")
31 answer
= string.gsub(answer
, "\r\n", "")
32 answer
= string.gsub(answer
, "\n", "")
33 if answer
== '' or answer
== nil then answer
= default
end
37 ------------ FILE READING
38 ReadDumpFile
= function (filename
)
40 filename
= filename
or 'dumpdata.bin'
41 if #filename
== 0 then
42 return nil, 'Filename length is zero'
45 infile
= io
.open(filename
, "rb")
47 return nil, string.format("Could not read file %s",filename
)
49 local t
= infile
:read("*all")
52 local _
,hex
= bin
.unpack(("H%d"):format(len
),t
)
56 ------------ FILE WRITING (EML)
57 --- Writes an eml-file.
58 -- @param uid - the uid of the tag. Used in filename
59 -- @param blockData. Assumed to be on the format {'\0\1\2\3,'\b\e\e\f' ...,
60 -- that is, blockData[row] contains a string with the actual data, not ascii hex representation
61 -- return filename if all went well,
62 -- @reurn nil, error message if unsuccessful
63 WriteDumpFile
= function(uid
, blockData
)
64 local destination
= string.format("%s.eml", uid
)
65 local file
= io
.open(destination
, "w")
67 return nil, string.format("Could not write to file %s", destination
)
69 local rowlen
= string.len(blockData
[1])
71 for i
,block
in ipairs(blockData
) do
72 if rowlen
~= string.len(block
) then
73 prlog(string.format("WARNING: Dumpdata seems corrupted, line %d was not the same length as line 1",i
))
76 local formatString
= string.format("H%d", string.len(block
))
77 local _
,hex
= bin
.unpack(formatString
,block
)
84 ------------ string split function
85 Split
= function( inSplitPattern
, outResults
)
86 if not outResults
then
90 local splitStart
, splitEnd
= string.find( self
, inSplitPattern
, start
)
92 table.insert( outResults
, string.sub( self
, start
, splitStart
-1 ) )
94 splitStart
, splitEnd
= string.find( self
, inSplitPattern
, start
)
96 table.insert( outResults
, string.sub( self
, start
) )
102 if s
== nil then return nil end
103 if #s
== 0 then return nil end
104 if type(s
) == 'string' then
105 local utils
= require('utils')
106 return utils
.ConvertAsciiToHex(
107 core
.iso14443b_crc(s
)
114 if s
== nil then return nil end
115 if #s
== 0 then return nil end
116 if type(s
) == 'string' then
117 local utils
= require('utils')
118 return utils
.ConvertAsciiToHex(
125 ------------ CRC-8 Legic checksum
126 -- Takes a hex string and calculates a crc8
127 Crc8Legic
= function(s
)
128 if s
== nil then return nil end
129 if #s
== 0 then return nil end
130 if type(s
) == 'string' then
131 local utils
= require('utils')
132 local asc
= utils
.ConvertHexToAscii(s
)
133 return core
.crc8legic(asc
)
137 ------------ CRC-16 Legic checksum
138 -- Takes data as hex string, uid hex and calculates a crc16 legic
139 Crc16Legic
= function(s
, uid
)
140 if s
== nil then return nil end
141 if #s
== 0 then return nil end
142 if uid
== nil then return nil end
143 if #uid
== 0 then return nil end
145 if type(s
) == 'string' then
146 local utils
= require('utils')
147 local asc
= utils
.ConvertHexToAscii(s
)
148 local uidstr
= utils
.ConvertHexToAscii(uid
)
149 return core
.crc16legic(asc
, uidstr
)
155 ------------ CRC-16 ccitt checksum
156 -- Takes a hex string and calculates a crc16
158 if s
== nil then return nil end
159 if #s
== 0 then return nil end
160 if type(s
) == 'string' then
161 local utils
= require('utils')
162 local asc
= utils
.ConvertHexToAscii(s
)
163 local hash
= core
.crc16(asc
)
170 ------------ CRC-64 ecma checksum
171 -- Takes a hex string and calculates a crc64 ecma hash
173 if s
== nil then return nil end
174 if #s
== 0 then return nil end
175 if type(s
) == 'string' then
176 local utils
= require('utils')
177 local asc
= utils
.ConvertHexToAscii(s
)
178 local hash
= core
.crc64(asc
)
183 ------------ CRC-64 ecma 182 checksum
184 -- Takes a hex string and calculates a crc64 ecma182 hash
185 Crc64_ecma182
= function(s
)
186 if s
== nil then return nil end
187 if #s
== 0 then return nil end
188 if type(s
) == 'string' then
189 local utils
= require('utils')
190 local asc
= utils
.ConvertHexToAscii(s
)
191 local hash
= core
.crc64_ecma182(asc
)
197 ------------ SHA1 hash
198 -- Takes a string and calculates a SHA1 hash
200 if s
== nil then return nil end
201 if #s
== 0 then return nil end
202 if type(s
) == 'string' then
207 -- Takes a hex string and calculates a SHA1 hash
208 Sha1Hex
= function(s
)
209 if s
== nil then return nil end
210 if #s
== 0 then return nil end
211 if type(s
) == 'string' then
212 local utils
= require('utils')
213 local asc
= utils
.ConvertHexToAscii(s
)
214 local hash
= core
.sha1(asc
)
221 -- input parameter is a string
222 -- Swaps the endianness and returns a number,
223 -- IE: 'cd7a' -> '7acd' -> 0x7acd
224 SwapEndianness
= function(s
, len
)
225 if s
== nil then return nil end
226 if #s
== 0 then return '' end
227 if type(s
) ~= 'string' then return nil end
231 local t
= s
:sub(3,4)..s
:sub(1,2)
232 retval
= tonumber(t
,16)
233 elseif len
== 24 then
234 local t
= s
:sub(5,6)..s
:sub(3,4)..s
:sub(1,2)
235 retval
= tonumber(t
,16)
236 elseif len
== 32 then
237 local t
= s
:sub(7,8)..s
:sub(5,6)..s
:sub(3,4)..s
:sub(1,2)
238 retval
= tonumber(t
,16)
243 -- input parameter is a string
244 -- Swaps the endianness and returns a string,
245 -- IE: 'cd7a' -> '7acd' -> 0x7acd
246 SwapEndiannessStr
= function(s
, len
)
247 if s
== nil then return nil end
248 if #s
== 0 then return '' end
249 if type(s
) ~= 'string' then return nil end
253 retval
= s
:sub(3,4)..s
:sub(1,2)
254 elseif len
== 24 then
255 retval
= s
:sub(5,6)..s
:sub(3,4)..s
:sub(1,2)
256 elseif len
== 32 then
257 retval
= s
:sub(7,8)..s
:sub(5,6)..s
:sub(3,4)..s
:sub(1,2)
261 ------------ CONVERSIONS
264 -- Converts DECIMAL to HEX
265 ConvertDecToHex
= function(decimal
)
270 local B
,DIGITS
,hex
= 16, "0123456789ABCDEF", ""
273 local remainder
= math
.fmod(decimal
, B
)
274 hex
= string.sub(DIGITS
, remainder
+ 1, remainder
+ 1) .. hex
275 decimal
= math
.floor(decimal
/ B
)
280 -- Convert Byte array to string of hex
281 ConvertBytesToHex
= function(bytes
, reverse
)
282 if bytes
== nil then return '' end
283 if #bytes
== 0 then return '' end
287 for i
= #bytes
, 1, -1 do
288 s
[i
] = string.format("%02X", bytes
[j
])
293 s
[i
] = string.format("%02X", bytes
[i
])
296 return table.concat(s
)
298 -- Convert byte array to string with ascii
299 ConvertBytesToAscii
= function(bytes
)
300 if bytes
== nil then return '' end
301 if #bytes
== 0 then return '' end
303 for i
= 1, #(bytes
) do
304 s
[i
] = string.char(bytes
[i
])
306 return table.concat(s
)
308 ConvertHexToBytes
= function(s
)
310 if s
== nil then return t
end
311 if #s
== 0 then return t
end
312 for k
in s
:gmatch
"(%x%x)" do
313 table.insert(t
,tonumber(k
,16))
317 ConvertAsciiToBytes
= function(s
, reverse
)
319 if s
== nil then return t
end
320 if #s
== 0 then return t
end
322 for k
in s
:gmatch
"(.)" do
323 table.insert(t
, string.byte(k
))
333 table.insert(rev
, t
[i
] )
339 ConvertHexToAscii
= function(s
, useSafechars
)
340 if s
== nil then return '' end
341 if #s
== 0 then return '' end
343 for k
in s
:gmatch
"(%x%x)" do
345 local n
= tonumber(k
,16)
347 if useSafechars
and ( (n
< 32) or (n
== 127) ) then
354 return table.concat(t
)
357 ConvertAsciiToHex
= function(s
)
358 if s
== nil then return '' end
359 if #s
== 0 then return '' end
361 for k
in s
:gmatch
"(.)" do
362 table.insert(t
, string.format("%02X", string.byte(k
)))
364 return table.concat(t
)
367 hexlify
= function(s
)
368 local u
= require('utils')
369 return u
.ConvertAsciiToHex(s
)
372 Chars2num
= function(s
)
373 return (s
:byte(1)*16777216)+(s
:byte(2)*65536)+(s
:byte(3)*256)+(s
:byte(4))
376 -- use length of string to determine 8,16,32,64 bits
377 bytes_to_int
= function(str
,endian
,signed
)
378 local t
= {str
:byte(1, -1)}
379 if endian
== "big" then --reverse bytes
388 n
= n
+ t
[k
] * 2^
((k
-1) * 8)
391 n
= (n
> 2^
(#t
*8-1) -1) and (n
- 2^
(#t
*8)) or n
-- if last bit set, negative.
396 -- a simple implementation of a sleep command. Thanks to Mosci
397 -- takes number of seconds to sleep
399 local clock = os
.clock
401 while clock() - t0
<= n
do end
405 -- function convertStringToBytes(str)
407 -- local strLength = string.len(str)
408 -- for i=1,strLength do
409 -- table.insert(bytes, string.byte(str, i))
415 -- function convertBytesToString(bytes)
416 -- local bytesLength = table.getn(bytes)
418 -- for i=1,bytesLength do
419 -- str = str .. string.char(bytes[i])
425 -- function convertHexStringToBytes(str)
427 -- local strLength = string.len(str)
428 -- for k=2,strLength,2 do
429 -- local hexString = "0x" .. string.sub(str, (k - 1), k)
430 -- table.insert(bytes, hex.to_dec(hexString))
436 -- function convertBytesToHexString(bytes)
438 -- local bytesLength = table.getn(bytes)
439 -- for i=1,bytesLength do
440 -- local hexString = string.sub(hex.to_hex(bytes[i]), 3)
441 -- if string.len(hexString) == 1 then
442 -- hexString = "0" .. hexString
444 -- str = str .. hexString