local skel_1 = [[
<html>
<head>
+
+ <script>
+ var dictionary = {}
+ function add(commaSeparated)
+ {
+ var fields = commaSeparated.split(",");
+ var manufacturerCode = fields[0];
+ var modelCode = fields[1];
+ var modelSubCode= fields[2];
+ var modelName = fields[3];
+ var ATQA = fields[4];
+ var SAK = fields[5];
+
+ //In the data below, wrong endian is used. Mifare is
+ // written as "0004" instead of "0400", so we need to
+ // flip it
+ ATQA = ATQA.substr(2,4)+ATQA.substr(0,2)
+
+ var info = {
+ modelCode : modelCode,
+ modelSubCode : modelSubCode,
+ modelName : modelName,
+ ATQA : ATQA,
+ SAK : SAK
+ }
+ console.log("Adding "+modelName+" , "+SAK)
+
+ dictionary[ATQA] = dictionary[ATQA] || [];
+ dictionary[ATQA].push(info)
+ }
+ function lookup(atqa, sak)
+ {
+ if (!dictionary[atqa]) return "UNKNOWN";
+
+ var possibleMatches = [];
+ for(var i = 0 ; i < dictionary[atqa].length ; i++)
+ {
+
+ var info = dictionary[atqa][i];
+ console.log("Comparing "+sak+ " with "+ info.SAK);
+ if(sak && info.SAK == sak)//exact match
+ {
+ return info.modelName;
+// possibleMatches.push(info.modelName);
+ }else //SAK unknown
+ {
+ possibleMatches.push(info.modelName);
+ }
+ }
+ if(possibleMatches.length > 0)
+ return possibleMatches.join(" or ");
+ return "UNKNOWN"
+ }
+
+ add("04,,,Mifare Mini,0004,09");
+ 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) 4K SL2,0004,11");
+ 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 Classic 4K,0002,18");
+ add("xx,,,NDEF Tags,0044,00 ");
+ 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,0044,08");
+ 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),0042,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),0044,11");
+ add("04,,,Mifare Plus (7 byte UID),0042,20");
+ add("04,,,Mifare Plus (7 byte UID),0044,20");
+ add("04,,,Mifare DesFire / DesFire EV1,0344,20067577810280");
+ add("04,,,JCOP31,0304,283877B14A434F503331");
+ add("04,,,JCOP31 v2.4.1,0048,207877B1024A434F5076323431");
+ add("04,,,JCOP41 v2.2,0048,203833B14A434F503431563232");
+ add("04,,,JCOP41 v2.3.1,0004,283833B14A434F50343156323331");
+ add("05,,,Mifare Classic 1K,0004,88");
+ add("40,,,MPCOS,0002,98");
+ add("25,,,Topaz/Topaz512/Jewel,0C00,");
+ add("1D,,,FM1208SH01,0004,53");
+ add("1D,,,FM1208,0008,20");
+ add("Nokia,,,Mifare Classic 4K emulated by Nokia 6212,0002,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,0102");
+ 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,0402");
+ 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,0702");
+ 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,0A02");
+ 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,0D02");
+ add("04,,,Smart MX with Mifare 4K emulation,0E02");
+ 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,0104");
+ 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,0404");
+ 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,0704");
+ 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,0A04");
+ 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,0D04");
+ add("04,,,Smart MX with Mifare 1K emulation,0E04");
+ 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,0148");
+ 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,0448");
+ 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,0748");
+ 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,0A48");
+ 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,0D48");
+ add("04,,,Smart MX with 7 byte UID,0E48");
+ add("04,,,Smart MX with 7 byte UID,0F48");
+</script>
+
<style>
* {
background-color: #2F3440;
background-color:#232323;
color : #F5E5C0;
- text-transform: uppercase;
+ xtext-transform: uppercase;
font-size: 1.05em;
font-family: monospace,Arial;
}
float:left;
border: 1px solid white;
}
- td{
- empty-cells : show;
+ td {
+ empty-cells: show;
}
- td.blockzero {
+ td.blockzero, .turqoise{
color: rgb(140, 245, 193);
}
- td.key_a{
+ td.key_a, .yellow{
color : #F8CA4D;
}
- td.key_b{
+ td.key_b, .blue{
color : #3F5666;
}
- td.accessconditions{
+ td.accessconditions, .red{
color : #EA6045;
}
}
</style>
<script>
+ /** Jquery for the poor **/
function dc(x){return document.createElement(x)}
- function addClass(el, line, byte)
- {
- if (line == 0)
- {
- el.className += " blockzero";
- }
-
- if(line < 128){
- linesPerSector = 4;
- }else
+ function tr(table){
+ var row = dc('tr');
+ table.appendChild(row);
+ return row;
+ }
+ function td(row, text){
+ var tdata = dc('td');
+ row.appendChild(tdata);
+ tdata.appendChild(document.createTextNode(text))
+ return tdata;
+ }
+
+ /**
+ * The identifiers that determine how to highlight data and present information
+ **/
+ var identifiers = [
+ function(data)
{
- //Quadruple size sectors
- linesPerSector = 16;
- line = line - 128;
+ // Should be 32 characters long ( 16 bytes per block)
+ if(data[0].length != 32) { return false; }
+ // ... add more checks if necessary ...
- }
+ var info = {Type : "Mifare"}
+ info['Size'] = (data[0].length / 2 * data.length) + " Bytes";
+ info['UID'] = data[0].substring(0,8);
+ info['SAK'] = data[0].substring(10,12);
+ info['ATQA'] = data[0].substring(12,16);
- if(line % linesPerSector == 0)
- {
- el.className += " sectorhdr";
- }
- if(line % linesPerSector == (linesPerSector -1))
+ info['Name'] = lookup(info.ATQA, info.SAK);
+ return {info: info, highlighter : mifareHighlighter }
+ },
+ function(data)
{
- el.className += " sectortrailer";
- if(byte == undefined)
- {
- return;
- }
+ // 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";
- if(byte < 6) el.className += " key_a";
- else if(byte < 10) el.className += " accessconditions";
- else el.className += " key_b";
+ return {info: info, highlighter : ndefHighligheter }
+ },
+ function(data)
+ {//This is the catch-all
+ return {info: {type : "Unknown"}, highlighter : noHighlighter}
}
+ ]
+
- }
-
+ /**
+ * Helper function to convert bin-data into printable chars
+ **/
- function loadMifare(data)
- {
- var data = data.data;
- var t = dc("table")
- for(var i = 0 ; i < data.length ; i++)
- {
- line = data[i];
- var tr = dc("tr");
- t.appendChild(tr);
- addClass(tr,i);
- var bytes = line.match(/(.{1,2})/g);
- for(var b = 0 ; b < bytes.length ; b++)
- {
- var td = dc('td');
- tr.appendChild(td);
- td.appendChild(document.createTextNode(bytes[b]));
- addClass(td,i,b);
- }
- }
- document.body.appendChild(t);
- }
function to_ascii(hexval)
{
var intval = parseInt(hexval,16);
return ".";
}
- function loadAscii(data)
+
+ function loadIntoTable(data, info, ascii)
{
- var data = data.data;
var t = dc("table")
for(var i = 0 ; i < data.length ; i++)
{
line = data[i];
- var tr = dc("tr");
- t.appendChild(tr);
+ var row = tr(t);
var bytes = line.match(/(.{1,2})/g);
for(var b = 0 ; b < bytes.length ; b++)
{
- var td = dc('td');
- tr.appendChild(td);
- td.appendChild(document.createTextNode(to_ascii(bytes[b])))
- addClass(td,i,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 load(data)
+ function handle(dump)
{
- loadMifare(data);
- loadAscii(data);
+ var data = dump.data;
+ var info = null;
+ for(var i = 0; i < identifiers.length && !info; i++)
+ info = identifiers[i](data);
+
+ console.log(info);
+
+ loadIntoTable(data, info, false);
+ loadIntoTable(data, info, true);
+ 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>
</head>
-<body>
-</body>
+<body></body>
<script>
- (function(){
-
- var x = {
- data :
+ var x = { data :
]]
local skel_2 = [[
- }
- load(x);
- })();
+ };
+ handle(x);
</script>
</html>
+
]]
local function getHTML(data)
return skel_1 .. data .. skel_2