diff --git a/CHANGELOG.md b/CHANGELOG.md index 1801fe3e1..d39822c95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Modified `data_hex_crc.lua` script, it now takes a `-s` parameter and the output is now in alternative row colors. (@iceman1001) - Added `hf mfdes brutedamslot` command (@kormax) - Added `hf mfdes getdelegateappinfo` command (@kormax) - Added `hf secc info` command to retrieve the Card Recognition Template(@antiklesys) diff --git a/client/luascripts/data_hex_crc.lua b/client/luascripts/data_hex_crc.lua index a970eaf93..89662ce4e 100644 --- a/client/luascripts/data_hex_crc.lua +++ b/client/luascripts/data_hex_crc.lua @@ -4,19 +4,21 @@ local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ This script calculates many checksums (CRC) over the provided hex input. ]] example = [[ - script run data_hex_crc -b 010203040506070809 - script run data_hex_crc -b 010203040506070809 -w 16 + script run data_hex_crc -d 010203040506070809 + script run data_hex_crc -d 010203040506070809 -w 16 + script run data_hex_crc -d 010203040506070809 -w 16 -s 47ED ]] usage = [[ -script run data_hex_crc [-b ] +script run data_hex_crc [-d ] ]] arguments = [[ - -b data in hex + -d data in hex + -s search for a value in the calculated crc and mark it green -w bitwidth of the CRC family of algorithm. defaults to all known CRC presets. ]] --- @@ -58,38 +60,110 @@ end -- The main entry point function main(args) + local search local data local width = 0 -- Read the parameters - for o, a in getopt.getopt(args, 'hb:w:') do + for o, a in getopt.getopt(args, 'hd:w:s:') do if o == 'h' then return help() end - if o == 'b' then data = a end + if o == 'd' then data = a end + if o == 's' then search = a end if o == 'w' then width = a end end + -- sanitize lua args parsing data = data or '01020304' width = width or 0 + search = search or 0 - print( string.rep('-',60) ) - print('Bit width of CRC | '..width) - print('Bytes | '..data) + local seplen = math.min(math.max(#('CRC width... '..width), #('Bytes....... '..data)), 80) + local sep = string.rep('-', seplen) + + -- header print('') - print( ('%-20s| %-16s| %s'):format('Model','CRC', 'CRC reverse','bigEnd', 'bigEnd','little','little')) - print( string.rep('-',60) ) + print(ansicolors.cyan.. 'CRC calculations' .. ansicolors.reset) + print(sep) + print('CRC width... '..width) + print('Bytes....... ' .. ansicolors.green .. data .. ansicolors.reset) + print(sep) + print('') + local lists, err = core.reveng_models(width) + if lists == nil then return oops(err) end + -- first pass: compute all values and find max CRC length + local results = {} + local maxlen = 0 for _,i in pairs(lists) do if string.len(i) > 1 then - local a1 = core.reveng_runmodel(i, data, false, '0') - local a2 = core.reveng_runmodel(i, data, true, '0') - local a3 = core.reveng_runmodel(i, data, false, 'b') - local a4 = core.reveng_runmodel(i, data, false, 'B') - local a5 = core.reveng_runmodel(i, data, false, 'l') - local a6 = core.reveng_runmodel(i, data, false, 'L') - print( ('%-20s| %-16s| %-16s| %-16s| %-16s| %-16s| %-16s'):format(i, a1:upper(), a2:upper(),a3:upper(),a4:upper(),a5:upper(),a6:upper() ) ) + + -- model name, hex, reverse, endian + local a1 = core.reveng_runmodel(i, data, false, '0'):upper() + local a2 = core.reveng_runmodel(i, data, true, '0'):upper() + local a3 = core.reveng_runmodel(i, data, false, 'b'):upper() + local a4 = core.reveng_runmodel(i, data, false, 'B'):upper() + local a5 = core.reveng_runmodel(i, data, false, 'l'):upper() + local a6 = core.reveng_runmodel(i, data, false, 'L'):upper() + + results[#results+1] = {i, a1, a2, a3, a4, a5, a6} + + for _, v in ipairs({a1, a2, a3, a4, a5, a6}) do + if #v > maxlen then + maxlen = #v end + end + end + end + + table.sort(results, function(a, b) + local na = tonumber(a[1]:match('^%a+%-(%d+)')) or 0 + local nb = tonumber(b[1]:match('^%a+%-(%d+)')) or 0 + if na ~= nb then return na < nb end + return a[1]:lower() < b[1]:lower() + end) + + -- column width = crc length + one space each side + local cw = maxlen + 2 + + local hcols = { + {'', 'CRC'}, + {'CRC', 'rev'}, + {'', 'be'}, + {'', 'BE'}, + {'', 'le'}, + {'', 'LE'}, + } + + local function hrow(line) + local cells = {} + for _, h in ipairs(hcols) do + cells[#cells+1] = ('%-'..(cw - 1)..'s'):format(h[line]) + end + return cells + end + + print(('%-24s| '):format('') .. table.concat(hrow(1), '| ')) + print(('%-24s| '):format('Model') .. table.concat(hrow(2), '| ')) + print( string.rep('-', 26 + (cw + 1) * 6) ) + + local row = 0 + for _, entry in ipairs(results) do + local name = entry[1] + row = row + 1 + local base = (row % 2 == 1) and ansicolors.yellow or '' + + local function fmt(v) + local cell = ('%-'.. (cw-1) ..'s'):format(v) -- one space left pad, right-pad to cw + if search ~= 0 and v == search:upper() then + return ansicolors.green .. cell .. ansicolors.reset .. base + end + return cell + end + + local values = fmt(entry[2]) ..'| '.. fmt(entry[3]) ..'| '.. fmt(entry[4]) ..'| '.. fmt(entry[5]) ..'| '.. fmt(entry[6]) ..'| '.. fmt(entry[7]) + print(base .. ('%-24s| '):format(name) .. values .. ansicolors.reset) end end