Delacorte Numbers

There really isn’t such a mathematical term – it was introduced at the latest Al Zimmermann’s Programming Contests and is defined in the contest rules (at azpcs.net – site should be back up around mid December January, a replacement is currently up at trdb.org ).

As I’m participating in this contest and have created some useful C++ classes to solve these types of optimisation problems I’ll be publishing them on github after cleaning them up when the contest is over (January 3rd).

JSON to HTML bullet points

I needed to convert a JSON hierarchy to an HTML bullet hierarchy and all the solutions I found on the Web were overkill. Enjoy.

<!DOCTYPE html>
<head>
<script>
var g_tree = {
   "1":{
      "11":{
         "111":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "112":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "113":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      },
      "12":{
         "121":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "122":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "123":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      },
      "13":{
         "131":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "132":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "133":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      }
   },
   "0":{
      "21":{
         "211":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "212":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "213":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      },
      "20":{
         "221":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "222":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "223":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      },
      "23":{
         "231":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "232":{
            "option1":1,
            "option2":1,
            "option3":1
         },
         "233":{
            "option1":1,
            "option2":1,
            "option3":1
         }
      }
   }
};

function json2ul(json, str)
{
        if (typeof(json)!='object')
                return '';

        str += '<ul>';
        var names = [];
        for (key in json)
                names.push(key);
        names.sort();
        var len = names.length;
        for (var i=0; i<len; i++) {
                var key = names[i];
                str += "<li>"+key;
                str += json2ul(json[key], '');
                str += "</li>";
        }
        str += '</ul>';

        return str;
}

function init()
{
        document.body.innerHTML=json2ul(g_tree, '');
}
</script>
</head>
<body onLoad='init()'>
</body>
</html>

Atom editor on Ubuntu

To Install the atom editor for Linux (taken from here):

$ sudo add-apt-repository ppa:webupd8team/atom
$ sudo apt-get update
$ sudo apt-get install atom

I needed syntax highlighting for Lua. My suggestion is:

  • Start atom, press <Ctrl><Shift>P
  • Type: install packages
  • Select ‘Settings View: Install Packages’
  • Search for language-lua package
  • install the language-lua package

You should get the syntax highlighting + other goodies explained here

Ubuntu 14.04 LTS very slow on VirtualBox

Got the solution from here:

  • Shut down the guest machine
  • Select the Ubuntu 14.04 virtual machine and click the Settings button
  • Select the ‘Display’ item from the list on the left
  • In the Video tab on the right, check the ‘Enable 3D Video Acceleration’ option
  • Select the ‘Storage’ item from the list on the left
  • In the ‘Storage Tree’ view on the right, select the Controller:SATA item
  • In the corresponding attributes to it’s right, check the ‘Use Host I/O Cache’ option
  • Close the settings and restart the virtual machine. It should be considerably faster now.

VirtualBox, Ubuntu Guest, Shared folders

Assuming your Ubuntu guest username is USERNAME:

  1. Make sure you have already installed the VirtualBox Guest Additions in the Ubuntu guest machine

  2. From the Ubuntu guest: sudo adduser USERNAME vboxsf

  3. Using the VirtualBox UI (Devices->Shared Folder Settings…) add the folder in the hosting machine that you wish to share.

  4. Restart the Ubuntu guest! (wasted too much time on that…)

  5. ls /media/ – you’ll find your shared folder there. You might wish to mount it to a different directory on your Ubuntu guest

Sniffing HTTP and HTTPS traffic to understand app protocols

I needed to understand the protocol between an iPhone application and the server. There was no written documentation and the company that owned the application wanted me to build something based on the protocol.

The first thing I tried was using squid as a proxy to intercept the protocol between the iPhone application and the server (click the info icon on the WiFi connection and set the HTTP proxy to the IP and port where the proxy runs on the machine that does the sniffing).

This almost worked. Almost, because squid was not able to proxy the HTTPS traffic to Facebook, which was necessary before connecting to the application server.

So, at this point I installed mitmproxy, a man-in-the-middle proxy that can sniff both HTTP and HTTPS traffic.
To sniff HTTPS traffic, mitmproxy on one hand presents to the client (the iPhone application in this case) a fake Facebook certificate, and on the other hand, presents itself to Facebook as if it were the original client.

For the client to accept the fake Facebook certificate, it has to be both known to the mitmproxy and also installed as a trusted certificate on the device.

For the certificate to be known to mitmproxy it should be created and passed as a parameter. This is achieved as follows (thanks to Nathan):

> openssl genrsa -out fake_facebook_ca.key 2048
> openssl req -new -x509 -key fake_facebook_ca.key -out fake_facebook_ca.crt

   ... No need to fill out optional fields ...
   Common Name (eg, YOUR name) []:*.facebook.com  (domain you want to MITM here)
   ...

> cat fake_facebook_ca.key fake_facebook_ca.crt > fake_facebook_ca.pem 
> mitmproxy --cert=fake_facebook_ca.pem

However, the above is not enough since the client has to trust this fake certificate. To do that, send the fake_facebook_ca.crt file as an attachment to an email and open this attachment on the iPhone on which the application that you want to sniff is located. You’ll be prompted whether you authorise installing and trusting this certificate. After confirming, open the application and you’ll be able too sniff the entire HTTP/HTTPS session on the mitmproxy console.

Errors installing Ubuntu guest additions on VirtualBox

If you mount the guest additions and see a warning about missing kernel headers, and the additions don’t seem to work, and then after trying to launch the guest additions CD again you get VERR_PDM_MEDIA_LOCKED error and everything starts going downhill from there – this is the solution that worked for me:

1. Reinstall Ubuntu

2. Before installing the guest additions:

sudo apt-get update
sudo apt-get install build-essential linux-headers-`uname -r` dkms

3. Now launch the guest additions CD

Simple CSV read and write using Lua

Update Dec 5th 2014: Fixed and updated the code.
Update Mar 9th 2017: Updated the code to handle null values in CSV.

This is a simplified Lua script to read and write CSV files. It assumes the separator character does not exist in one of the values.

I don’t know why I couldn’t find a simple code snippet to do this on the net, but sometimes it’s just faster to write it than to search for it. Hopefully this will save you that time too:

--[[
-------------------------------
Save this file as simplecsv.lua
-------------------------------

Example use: Suppose file csv1.txt is:

1.23,70,hello
there,9.81,102
x,y,,z
8,1.243,test

Then the following
-------------------------------------
local csvfile = require "simplecsv"
local m = csvfile.read('./csv1.txt') -- read file csv1.txt to matrix m
print(m[2][3])                       -- display element in row 2 column 3 (102)
m[1][3] = 'changed'                  -- change element in row 1 column 3
m[2][3] = 123.45                     -- change element in row 2 column 3
csvfile.write('./csv2.txt', m)       -- write matrix to file csv2.txt
-------------------------------------

will produce file csv2.txt with the contents:

1.23,70,changed
there,9.81,123.45
x,y,,z
8,1.243,test

the read method takes 4 parameters:
path: the path of the CSV file to read - mandatory
sep: the separator character of the fields. Optionsl, defaults to ','
tonum: whether to convert fields to numbers if possible. Optional. Defaults to true
null: what value should null fields get. Optional. defaults to ''
]]

module(..., package.seeall)

---------------------------------------------------------------------
function string:split(sSeparator, nMax, bRegexp)
    if sSeparator == '' then
        sSeparator = ','
    end

    if nMax and nMax < 1 then
        nMax = nil
    end

    local aRecord = {}

    if self:len() > 0 then
        local bPlain = not bRegexp
        nMax = nMax or -1

        local nField, nStart = 1, 1
        local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
        while nFirst and nMax ~= 0 do
            aRecord[nField] = self:sub(nStart, nFirst-1)
            nField = nField+1
            nStart = nLast+1
            nFirst,nLast = self:find(sSeparator, nStart, bPlain)
            nMax = nMax-1
        end
        aRecord[nField] = self:sub(nStart)
    end

    return aRecord
end

---------------------------------------------------------------------
function read(path, sep, tonum, null)
    tonum = tonum or true
    sep = sep or ','
    null = null or ''
    local csvFile = {}
    local file = assert(io.open(path, "r"))
    for line in file:lines() do
        fields = line:split(sep)
        if tonum then -- convert numeric fields to numbers
            for i=1,#fields do
                local field = fields[i]
                if field == '' then
                    field = null
                end
                fields[i] = tonumber(field) or field
            end
        end
        table.insert(csvFile, fields)
    end
    file:close()
    return csvFile
end

---------------------------------------------------------------------
function write(path, data, sep)
    sep = sep or ','
    local file = assert(io.open(path, "w"))
    for i=1,#data do
        for j=1,#data[i] do
            if j>1 then file:write(sep) end
            file:write(data[i][j])
        end
        file:write('\n')
    end
    file:close()
end

---------------------------------------------------------------------