Factlet for the day …
Since the start of March my spamassassin filter has caught over 14,500 instances of spam.
Since the start of March my spamassassin filter has caught over 14,500 instances of spam.
Interesting Firefox extension (although it’s more of a complete mod): Conkeror. This adds a complete new chrome that makes Firefox look and feel like emacs. There’s even Vi bindings too if you feel that way.
The university recently moved to a new positions-vacant system so I’ve rewritten the RSS generator for the feeds. Rather than generate different feeds based on position type they’re all in one this time around:
http://people.vislab.usyd.edu.au/~ssmith/rss/Usyd-Vacancies.xml
Included in the Bittorrent protocol is a simple text-based data-serialisation format referred to as bencoding. This is useful outside the context of Bittorrent for producing quick line-based network protocols (the original version of the AG replacement project used it for a simplified form of RPC).
My language to learn this year is Erlang, and as a back-to-basics exercise I spent a bit of time this weekend implementing the decoder part of a bencoding module. To resulting code turns out to be surprisingly terse, due in part to Erlang’s declarative nature: matching, guards and recursion can perform much of the functionality of more verbose loops, ifs and cases:
-module(bencode).
-export([bdecode/1]).
-import(string, [substr/2, substr/3, to_integer/1, chr/2]).
bdecode([Char | _Rest] = Str) when Char >= $0, Char =< $9 ->
ColIdx = chr(Str, $:),
IntStr = substr(Str, 1, ColIdx-1),
{Len, _} = to_integer(IntStr),
Result = substr(Str, ColIdx+1, Len),
Rest = substr(Str, ColIdx+Len+1),
{{string, Result}, Rest};
bdecode([Char | Rest]) when Char == $i ->
End = chr(Rest, $e),
{Result, _} = to_integer(substr(Rest, 1, End-1)),
{{int, Result}, substr(Rest, End+1)};
bdecode([Char | Rest]) when Char == $l ->
{List, Rem} = dolist(Rest),
{{list, List}, Rem};
bdecode([Char | Rest]) when Char == $d ->
{Dict, Rem} = dodict(Rest),
{{dict, Dict}, Rem}.
dolist(Str) ->
dolist(Str, []).
dolist([Char | Rest], List) when Char == $e ->
{List, Rest};
dolist(Str, List) ->
{Result, Rest} = bdecode(Str),
dolist(Rest, lists:append(List, [Result])).
dodict(Str) ->
dodict(Str, dict:new()).
dodict([Char | Rest], Dict) when Char == $e ->
{Dict, Rest};
dodict(Str, Dict) ->
{{string, Key}, Rest} = bdecode(Str),
{Val, Rest2} = bdecode(Rest),
dodict(Rest2, dict:store(Key, Val, Dict)).