<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Intrepid Blog</title><link>https://blog.affien.com/</link><description>A few thoughts</description><language>en-us</language><lastBuildDate>Sat, 13 Nov 2021 13:22:17 +0100</lastBuildDate><atom:link href="https://blog.affien.com/feed/index.xml" rel="self" type="application/rss+xml"/><item><title>Sizing Up Post-Quantum Signatures</title><link>https://blog.affien.com/archives/2021/11/13/sizing-up-post-quantum-signatures/</link><pubDate>Sat, 13 Nov 2021 13:22:17 +0100</pubDate><guid>https://blog.affien.com/archives/2021/11/13/sizing-up-post-quantum-signatures/</guid><description>&lt;p&gt;The future is &lt;a href="https://en.wikipedia.org/wiki/Post-quantum_cryptography"&gt;Post-Quantum&lt;/a&gt;. Unfortunately, post-quantum cryptography is larger, especially the signatures. How much room is there in TLS? &lt;a href="https://blog.cloudflare.com/sizing-up-post-quantum-signatures/"&gt;I had a look.&lt;/a&gt;&lt;/p&gt;</description></item><item><title>demandimport: load python modules on-demand</title><link>https://blog.affien.com/archives/2015/12/05/demandimport-load-python-modules-on-demand/</link><pubDate>Sat, 05 Dec 2015 20:09:54 +0100</pubDate><guid>https://blog.affien.com/archives/2015/12/05/demandimport-load-python-modules-on-demand/</guid><description>&lt;p&gt;A typical python app starts with lots of &lt;code&gt;import&lt;/code&gt;s of modules which are not always used. Usually this isn’t a problem. However, if you are writing a commandline-util in Python which should be snappy, every fraction of a second counts. &lt;a href="https://www.mercurial-scm.org"&gt;Mercurial&lt;/a&gt;, the SCM written in Python, loads its modules on-demand to be snappy. I took their code and packaged it into a separate module &lt;code&gt;demandimport&lt;/code&gt; such that everyone can use it for their own command-line utils.&lt;/p&gt;
&lt;p&gt;Its use is simple:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;import demandimport; demandimport.enable()&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can find demandimport on &lt;a href="https://github.com/bwesterb/py-demandimport"&gt;github&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Use MacPort’s ssh-agent</title><link>https://blog.affien.com/archives/2015/09/07/use-macports-ssh-agent/</link><pubDate>Mon, 07 Sep 2015 14:33:34 +0100</pubDate><guid>https://blog.affien.com/archives/2015/09/07/use-macports-ssh-agent/</guid><description>&lt;p&gt;The version of &lt;code&gt;ssh&lt;/code&gt; that ships with Mac OS X is quite old. If you want a more recent version to use, for instance, ECDSA or ED25519 keypairs you can install a more recent version of &lt;code&gt;ssh&lt;/code&gt; using &lt;a href="https://www.macports.org"&gt;MacPorts&lt;/a&gt; with &lt;code&gt;sudo port install openssh +gsskex&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, OS X won’t remember your fancy ECDSA or ED25519 key passwords in the KeyChain. This is because the old &lt;code&gt;ssh-agent&lt;/code&gt; is running in the background. This is how to run MacPort’s &lt;code&gt;ssh-agent&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t forget to install &lt;code&gt;openssh&lt;/code&gt; with the &lt;code&gt;+gsskex&lt;/code&gt; variant. Otherwise &lt;code&gt;ssh-agent&lt;/code&gt; won’t even try to talk to the KeyChain.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;launchctl unload -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist&lt;/code&gt; to disable Mac’s old &lt;code&gt;ssh-agent&lt;/code&gt;. Note: run this under your user account — not as root.&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;/System/Library/LaunchAgents/org.openbsd.ssh-agent.plist&lt;/code&gt; to &lt;code&gt;~/Library/LaunchAgents/org.macports.ssh-agent.plist&lt;/code&gt; and open the copy in an editor. In the copy, replace &lt;code&gt;/usr/bin/ssh-agent&lt;/code&gt; with &lt;code&gt;/opt/local/bin/ssh-agent&lt;/code&gt; and &lt;code&gt;org.openbsd.ssh-agent&lt;/code&gt; with &lt;code&gt;org.macports.ssh-agent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;launchctl load -S Aqua -w ~/Library/LaunchAgents/org.macports.ssh-agent.plist&lt;/code&gt; to enable the &lt;code&gt;ssh-agent&lt;/code&gt; from MacPorts. Again, run this as under your user account — not as root.&lt;/li&gt;
&lt;li&gt;Logout and login again.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That should do it. These steps are an updated version of &lt;a href="http://bridge.grumpy-troll.org/2011/07/diversion-into-macosx-launchd--ssh-agent/"&gt;this guide&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Setup Ubuntu IPv4/IPv6 router for VLAN-tagged PPPoE internet connection</title><link>https://blog.affien.com/archives/2015/05/28/setup-ubuntu-ipv4ipv6-router-for-vlan-tagged-pppoe-internet-connection/</link><pubDate>Thu, 28 May 2015 11:46:45 +0100</pubDate><guid>https://blog.affien.com/archives/2015/05/28/setup-ubuntu-ipv4ipv6-router-for-vlan-tagged-pppoe-internet-connection/</guid><description>&lt;p&gt;My ISP, &lt;a href="http://xs4all.nl"&gt;XS4ALL&lt;/a&gt;, delivers IPv4/IPv6 over fiber via VLAN-tagged PPPoE. Normally, you would use the (excellent) WiFi-router they lend you, but if you want a little more control you can install your own computer as router. In this post I will explain how to do this with Ubuntu 15.04. Some steps are specific to my ISP, but most of it will also apply to any other provider using PPPoE.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rename interfaces&lt;/strong&gt;&lt;br&gt;
The router should have at least two interfaces: one to connect to the fiber-modem and the other for the LAN. It is convenient to rename the interfaces. Create a file &lt;code&gt;/etc/udev/rules.d/10-persistent-network-names.rules&lt;/code&gt; containing&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SUBSYSTEM==&amp;#34;net&amp;#34;, ACTION==&amp;#34;add&amp;#34;, KERNEL==&amp;#34;em1&amp;#34;, ATTRS{address}==&amp;#34;12:34:45:67:89:0a&amp;#34;, NAME=&amp;#34;modem&amp;#34;
SUBSYSTEM==&amp;#34;net&amp;#34;, ACTION==&amp;#34;add&amp;#34;, KERNEL==&amp;#34;eth0&amp;#34;, ATTRS{address}==&amp;#34;12:34:45:67:89:0a&amp;#34;, NAME=&amp;#34;modem&amp;#34;
SUBSYSTEM==&amp;#34;net&amp;#34;, ACTION==&amp;#34;add&amp;#34;, ATTRS{address}==&amp;#34;0a:89:67:45:23:12&amp;#34;, NAME=&amp;#34;lan&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replace the MAC addresses by the corresponding MAC addresses of your interfaces (you can find them using &lt;code&gt;ifconfig | grep HWaddr&lt;/code&gt;) and &lt;code&gt;em1&lt;/code&gt; by the current name of the interface connected to the modem. Note that we have two rules for the modem interface: this is to prevent udev form renaming the VLAN interface. If you know a nicer way, please let me know. Reboot and test whether this worked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configure interfaces&lt;/strong&gt;&lt;br&gt;
Add the following to &lt;code&gt;/etc/network/interfaces&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;auto modem
iface modem inet manual
 mtu 1508

auto modem.6
iface modem.6 inet manual
 vlan-raw-device modem
 mtu 1508

auto lan
iface lan inet static
 address 10.0.0.1
 netmask 255.255.255.0

auto wan
iface wan inet ppp
 pre-up /bin/ip link set modem.6 up
 provider xs4all

iface wan inet6 auto
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The block for &lt;code&gt;modem&lt;/code&gt; is only used to set its MTU to 1508. We need this if we want to set the MTU of the PPPoE connection to the normal 1500 (and compensate for the 8 bytes PPPoE uses). If you run into trouble, you can leave all MTU declarations out.&lt;/p&gt;
&lt;p&gt;The block &lt;code&gt;modem.6&lt;/code&gt; configures an interface for packets on &lt;code&gt;modem&lt;/code&gt; tagged with VLAN ID 6. XS4ALL uses VLAN tagging such that it can deliver different services (internet on 6, TV on 4, …) via the same modem.&lt;/p&gt;
&lt;p&gt;The block &lt;code&gt;lan&lt;/code&gt; sets up the interface for a LAN on &lt;code&gt;10.0.0.x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;code&gt;wan&lt;/code&gt; block tells the system to set-up a PPP-interface using the configuration named &lt;code&gt;xs4all&lt;/code&gt;. We will set that up in a moment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Set-up PPPoE&lt;/strong&gt;&lt;br&gt;
Install the package &lt;code&gt;pppoe&lt;/code&gt; and create &lt;code&gt;/etc/ppp/peers/xs4all&lt;/code&gt; with the contents&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
ifname wan
noipdefault
+ipv6 ipv6cp-use-ipaddr
defaultroute
connect /bin/true
noauth
persist
mtu 1500
mru 1500
noaccomp
default-asyncmap
plugin rp-pppoe.so modem.6
user &amp;#34;someuser@xs4all.nl&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also create &lt;code&gt;/etc/ppp/chap-secrets&lt;/code&gt; with&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
&amp;#34;someuser@xs4all.nl&amp;#34; * &amp;#34;somepassword&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My ISP requires the authentication step, but (intentionally) does not check the username and password — you can fill in anything you like.&lt;/p&gt;
&lt;p&gt;Reboot. You should have IPv4 &lt;em&gt;on the router&lt;/em&gt;. (The rest: DNS, IPv6, IPv4 on the LAN shouldn’t work.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LAN&lt;/strong&gt;&lt;br&gt;
We’re ready to set up the LAN. We will use &lt;code&gt;dnsmasq&lt;/code&gt; as it will act as (caching) DNS server, DHCP server and RA (IPv6’s alternative to DHCP) server. Install &lt;code&gt;dnsmasq&lt;/code&gt; and write the following to &lt;code&gt;/etc/dnsmasq.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
domain-needed
bogus-priv
filterwin2k
resolv-file=/etc/resolv.conf-dnsmasq
local=/lan/
expand-hosts
domain=lan
interface=lan
dhcp-range=lan,10.0.0.50,10.0.0.150,255.255.255.0,12h
dhcp-option=tag:lan,option:router,10.0.0.1
dhcp-authoritative
enable-ra
dhcp-range=::1,constructor:lan,ra-stateless,ra-names,12h
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In &lt;code&gt;/etc/resolv.conf&lt;/code&gt;, put:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nameserver 10.0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You might want to remove the package &lt;code&gt;resolvconf&lt;/code&gt; as it might interfere. Now, in &lt;code&gt;/etc/resolv.conf-dnsmasq&lt;/code&gt;, put the actual DNS server you would like to use. For Google’s public DNS, write:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nameserver 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We’re almost done with the IPv4 LAN. To &lt;code&gt;/etc/sysctl.conf&lt;/code&gt; append&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will allow the kernel to forward packages between &lt;em&gt;all&lt;/em&gt; interfaces. If you have more interfaces, you might want to restrict the forwarding to &lt;code&gt;lan&lt;/code&gt; and &lt;code&gt;wan&lt;/code&gt;, but to configure this requires running a script at the creation of the interfaces.&lt;/p&gt;
&lt;p&gt;And finally, install &lt;code&gt;iptables-persistent&lt;/code&gt; and write to &lt;code&gt;/etc/iptables/rules.v4&lt;/code&gt;, the following for the IPv4 NAT:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wan -j MASQUERADE
COMMIT
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that this will allow any connections from outside to the router on any port. Also, without configuration &lt;code&gt;ip6tables&lt;/code&gt;, no connection is blocked form the outside. If you like a firewall (that is: whitelist which connections are allowed), you want to add some rules here.&lt;/p&gt;
&lt;p&gt;Reboot. You should have IPv4 &amp;amp; DNS on the router and LAN.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv6&lt;/strong&gt;&lt;br&gt;
My ISP assigns a &lt;code&gt;/48&lt;/code&gt; via &lt;code&gt;DHCPv6&lt;/code&gt;. Install &lt;code&gt;wide-dhcpv6-client&lt;/code&gt;. Change &lt;code&gt;/etc/wide-dhcpv6/dhcp6c.conf&lt;/code&gt; to&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;profile default
{
 script &amp;#34;/etc/wide-dhcpv6/dhcp6c-script&amp;#34;;
};

interface wan {
 send ia-pd 0;
};

id-assoc pd 0 {
 prefix-interface lan {
 sla-len 16;
 sla-id 0;
 ifid 1;
 }; 
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will request a subnet and assign it to the &lt;code&gt;lan&lt;/code&gt; interface. The IP of the router will be &lt;code&gt;thesubnet::1&lt;/code&gt; due to the &lt;code&gt;ifid&lt;/code&gt; setting.&lt;/p&gt;
&lt;p&gt;That’s it: reboot and enjoy your IPv4 &amp;amp; IPv6 connection.&lt;/p&gt;</description></item><item><title>Simple Elliptic Curve Cryptography in Python compatible with seccure</title><link>https://blog.affien.com/archives/2013/04/16/simple-elliptic-curve-cryptography-in-python-compatible-with-seccure/</link><pubDate>Tue, 16 Apr 2013 15:12:46 +0100</pubDate><guid>https://blog.affien.com/archives/2013/04/16/simple-elliptic-curve-cryptography-in-python-compatible-with-seccure/</guid><description>&lt;p&gt;Instead of RSA, you can use an Elliptic Curve algorithm for public/private key cryptography. The main advantage is that keys are a lot smaller. With RSA you need keyservers to distribute public keys. With Elliptic Curves, you can just write: my public key is &lt;code&gt;*jMVCU^[QC&amp;amp;q*v_8C1ZAFBAgD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There are two drawbacks: first, Elliptic Curve cryptography is even harder to understand than plain RSA &lt;em&gt;and&lt;/em&gt; secondly, there are only a few implementation of Elliptic Curve cryptography. In fact: I did not find any maintained Elliptic Curve package for Python.&lt;/p&gt;
&lt;p&gt;Thus I wrote a &lt;a href="https://github.com/bwesterb/py-seccure"&gt;Python package&lt;/a&gt; compatible with the excellent commandline utility &lt;a href="http://point-at-infinity.org/seccure/"&gt;seccure&lt;/a&gt; written by Poettering. Here are some examples of how to use the original commandline &lt;code&gt;seccure&lt;/code&gt; and how to do the same thing in Python.&lt;/p&gt;
&lt;p&gt;For a private key, you just pick a (long!) password. You can &lt;strong&gt;derive the public key&lt;/strong&gt; with &lt;code&gt;seccure&lt;/code&gt; as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ &lt;strong&gt;seccure-key&lt;/strong&gt;&lt;br/&gt;
Assuming curve p160.&lt;br/&gt;
Enter private key: &lt;strong&gt;my private key&lt;/strong&gt;&lt;br/&gt;
The public key is: 8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn&lt;br/&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Python&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;import seccure&lt;/strong&gt;&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;str(seccure.passphrase_to_pubkey(b'my private key'))&lt;/strong&gt;&lt;br/&gt;
'8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn'&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, to &lt;strong&gt;encrypt&lt;/strong&gt; a message for the public key:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ &lt;strong&gt;seccure-encrypt -o private.msg '8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn'&lt;/strong&gt;&lt;br/&gt;
Assuming MAC length of 80 bits.&lt;br/&gt;
Go ahead and type your message ...&lt;br/&gt;
&lt;strong&gt;This is a very secret message!&lt;br/&gt;
^D&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Python:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;ciphertext = seccure.encrypt(b'This is a very secret message\n', b'8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn')&lt;/strong&gt;&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;ciphertext&lt;/strong&gt;&lt;br/&gt;
'\x00\x146\x17\xe9\xc1\x1a\x7fkX\xec\xa0n,h&lt;/code&gt;…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To &lt;strong&gt;decrypt&lt;/strong&gt; the encrypted message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ &lt;strong&gt;seccure-decrypt -i private.msg&lt;/strong&gt;&lt;br/&gt;
Assuming MAC length of 80 bits.&lt;br/&gt;
Assuming curve p160.&lt;br/&gt;
Enter private key: &lt;strong&gt;my private key&lt;/strong&gt;&lt;br/&gt;
This is a very secret message!&lt;br/&gt;
Integrity check successful, message unforged!&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Python:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;seccure.decrypt(ciphertext, b'my private key')&lt;/strong&gt;&lt;br/&gt;
'This is a very secret message\n'&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To create a &lt;strong&gt;signature&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ &lt;strong&gt;seccure-sign&lt;/strong&gt;&lt;br/&gt;
Assuming curve p160.&lt;br/&gt;
Enter private key: &lt;strong&gt;my private key&lt;/strong&gt;&lt;br/&gt;
Go ahead and type your message ...&lt;br/&gt;
&lt;strong&gt;This message will be signed&lt;br/&gt;
^D&lt;/strong&gt;&lt;br/&gt;
Signature: $HPI?t(I*1vAYsl$|%21WXND=6Br*[&amp;gt;k(OR9B!GOwHqL0s+3Uq&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Python:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;seccure.sign(b'This message will be signed\n', b'my private key')&lt;/strong&gt;&lt;br/&gt;
'$HPI?t(I*1vAYsl$|%21WXND=6Br*[&amp;gt;k(OR9B!GOwHqL0s+3Uq'&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And to &lt;strong&gt;verify a signature&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ &lt;strong&gt;seccure-verify '8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn' '$HPI?t(I*1vAYsl$|%21WXND=6Br*[&amp;gt;k(OR9B!GOwHqL0s+3Uq'&lt;/strong&gt;&lt;br/&gt;
Go ahead and type your message ...&lt;br/&gt;
&lt;strong&gt;This message will be signed&lt;br/&gt;
^D&lt;/strong&gt;&lt;br/&gt;
Signature successfully verified!&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Python:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; &lt;strong&gt;seccure.verify(b'This message will be signed\n', b'$HPI?t(I*1vAYsl$|%21WXND=6Br*[&amp;gt;k(OR9B!GOwHqL0s+3Uq', b'8W;&amp;gt;i^H0qi|J&amp;amp;$coR5MFpR*Vn')&lt;/strong&gt;&lt;br/&gt;
True&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can find &lt;a href="https://github.com/bwesterb/py-seccure"&gt;the Python library on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update:&lt;/ins&gt; added support for Python 2.6, 2.7, 3.2 and 3.3.&lt;/p&gt;</description></item><item><title>msgpack for pypy</title><link>https://blog.affien.com/archives/2013/01/29/msgpack-for-pypy/</link><pubDate>Tue, 29 Jan 2013 23:24:38 +0100</pubDate><guid>https://blog.affien.com/archives/2013/01/29/msgpack-for-pypy/</guid><description>&lt;p&gt;&lt;a href="http://msgpack.org"&gt;msgpack&lt;/a&gt; is a fast and small binary format for &lt;a href="http://json.org"&gt;json&lt;/a&gt;. The Python &lt;code&gt;msgpack&lt;/code&gt; module is even a drop-in replacement for the &lt;code&gt;json&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://pypy.org"&gt;PyPy&lt;/a&gt; is an implementation of Python in Python with a &lt;a href="http://en.wikipedia.org/wiki/Tracing_just-in-time_compilation"&gt;tracing JIT&lt;/a&gt;. If your Python script runs for more than 1 second, it will probably be &lt;a href="http://speed.pypy.org"&gt;quite faster&lt;/a&gt; on PyPy.&lt;/p&gt;
&lt;p&gt;PyPy is almost a drop-in replacement for Python. Only extensions modules written in C can be a problem — for instance the &lt;code&gt;msgpack&lt;/code&gt; module.&lt;/p&gt;
&lt;p&gt;Thus I wrote a pure Python fallback for the msgpack module, which &lt;a href="https://github.com/msgpack/msgpack-python/pull/42"&gt;has been merged upstream&lt;/a&gt;. As a rough benchmark, I measured the pack and unpack time of a 30MB msgpack-object from the wild.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/~bas/images/msgpack-chart1.png"&gt;&lt;img src="http://w-nz.com/~bas/images/msgpack-chart1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The execution times for the fallback with normal Python are all off the chart (15.4s, 15.1s, 10.1s, 10.0s).&lt;/li&gt;
&lt;li&gt;PyPy is faster on the second run: it had time to trace and optimize at runtime.&lt;/li&gt;
&lt;li&gt;For packing, PyPy (nightly) is almost as fast as the original C extension.&lt;/li&gt;
&lt;li&gt;For unpacking, PyPy (nightly) is 340% slower. Yet it more than 10 times faster than normal Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;This code should be in the next official release of &lt;code&gt;msgpack-python&lt;/code&gt;. If you want to use it already, check out the &lt;a href="https://github.com/msgpack/msgpack-python"&gt;git repository&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first version did not run this fast on PyPy. With PyPy’s &lt;a href="https://bitbucket.org/pypy/jitviewer"&gt;jitviewer&lt;/a&gt; the compiled code and assumptions of PyPy can be examined. These are the tweaks I used in descending order of impact.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of &lt;code&gt;StringIO&lt;/code&gt;, the fallback uses PyPy’s own &lt;code&gt;StringBuilder&lt;/code&gt;. &lt;code&gt;StringIO&lt;/code&gt; allows writing, reading, seeking and what more. &lt;code&gt;StringBuilder&lt;/code&gt; only allows appending and thus it is easier for PyPy to optimize. This increased performance of packing by an order of magnitude.&lt;/li&gt;
&lt;li&gt;Using constant format strings for &lt;code&gt;struct.unpack&lt;/code&gt; allows PyPy to optimize it. Thus &lt;code&gt;struct.unpack(&amp;quot;I&amp;quot;, f.read(4)); f.read(n)&lt;/code&gt; instead of &lt;code&gt;struct.unpack(&amp;quot;I%ds&amp;quot;%n, f.read(4+n))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;stream.write(a); stream.write(b)&lt;/code&gt; instead of &lt;code&gt;stream.write(a+b)&lt;/code&gt; increased performance.&lt;/li&gt;
&lt;li&gt;Adding an explicit fastpath&lt;/li&gt;
&lt;li&gt;PyPy usually specializes a function well for its most common path, however in &lt;a href="https://github.com/msgpack/msgpack-python/commit/4cde7f080c16fd396d758930faf9ebf15b138047"&gt;some cases&lt;/a&gt; it needs help. In this case a function returns a concatenation of several strings. However: in the most common case it only does one: &lt;code&gt;ret=''; ret+=something; return ret&lt;/code&gt;. PyPy does not recognize that &lt;code&gt;ret&lt;/code&gt; is not needed at all in this case, so I added an if-statement before initializing it for the case where there is only one concatenation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clearly the unpacking code could be faster, if anyone with expertise on PyPy’s JIT would look at it, that would be great.&lt;/p&gt;</description></item><item><title>PyPy 2.0-beta1 for Debian Squeeze amd64</title><link>https://blog.affien.com/archives/2013/01/26/pypy-2-0-beta1-for-debian-squeeze-amd64/</link><pubDate>Sat, 26 Jan 2013 11:57:47 +0100</pubDate><guid>https://blog.affien.com/archives/2013/01/26/pypy-2-0-beta1-for-debian-squeeze-amd64/</guid><description>&lt;p&gt;I compiled &lt;a href="http://westerbaan.name/~bas/builds/pypy/pypy-2.0-beta1-squeeze-amd64.tar.bz2"&gt;PyPy 2.0-beta1 for Debian Squeeze amd64&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>FTL .dat packer and unpacker</title><link>https://blog.affien.com/archives/2012/09/14/ftl-dat-packer-and-unpacker/</link><pubDate>Fri, 14 Sep 2012 17:04:25 +0100</pubDate><guid>https://blog.affien.com/archives/2012/09/14/ftl-dat-packer-and-unpacker/</guid><description>&lt;p&gt;I wrote a simple Python script to pack and unpack the data files of the indie game &lt;a href="http://www.ftlgame.com"&gt;FTL&lt;/a&gt;, which is by the way quite enjoyable. You can find it &lt;a href="https://github.com/bwesterb/ftldat"&gt;here&lt;/a&gt; on github.&lt;/p&gt;</description></item><item><title>Fix excessive disk usage of Sparrow for Mac</title><link>https://blog.affien.com/archives/2012/08/12/fix-excessive-disk-usage-of-sparrow-for-mac/</link><pubDate>Sun, 12 Aug 2012 15:43:25 +0100</pubDate><guid>https://blog.affien.com/archives/2012/08/12/fix-excessive-disk-usage-of-sparrow-for-mac/</guid><description>&lt;p&gt;It may happen that &lt;a href="http://sprw.me"&gt;Sparrow for Mac&lt;/a&gt; uses an excessive amount of disk space. For only the headers of my 9GB of e-mail, Sparrow used 39GB. I found a work-around.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;br&gt;
Sparrow uses a &lt;a href="http://fallabs.com/tokyocabinet/"&gt;Tokyo Cabinet&lt;/a&gt;, called &lt;code&gt;data.tch&lt;/code&gt;, as storage. Mine was 39GB. What could eat up all that space? I only have 9GB of e-mail in total. With &lt;a href="https://gist.github.com/3332093"&gt;a simple script&lt;/a&gt; I looked into the cabinet and found it actually contained less than 1GB of data. The cabinet was wasting a lot of space by not being packed tightly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The work-around&lt;/strong&gt;&lt;br&gt;
To repack the Tokyo Cabinet, run:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;tchmgr optimize &amp;quot;~/Library/Containers/com.sparrowmailapp.sparrow/Data/Library/Application Support/Sparrow/&lt;strong&gt;(your-email@gmail.com)&lt;/strong&gt;.sparrowdb/data.db/data.tch&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Replace &lt;strong&gt;(your-email@gmail.com)&lt;/strong&gt; with your e-mail address. You can install the &lt;code&gt;tchmgr&lt;/code&gt; program using &lt;code&gt;sudo port install tokyocabinet&lt;/code&gt;, if you are a &lt;a href="http://www.macports.org"&gt;MacPorts&lt;/a&gt; user.&lt;/p&gt;
&lt;p&gt;This reduced the size of the cabinet to 1.1GB!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cause?&lt;/strong&gt;&lt;br&gt;
It is odd that the cabinet became so loosely packed. It may happen if Sparrow adds and removes a lot of entries, but there seems no reason for Sparrow to do this. There might be an underlying bug. I reported this issue to the developers, but they have yet to respond.&lt;/p&gt;</description></item><item><title>Bachelor thesis: on effective undecidability and Post’s problem</title><link>https://blog.affien.com/archives/2012/07/11/bachelor-thesis-on-effective-undecidability-and-posts-problem/</link><pubDate>Wed, 11 Jul 2012 11:49:48 +0100</pubDate><guid>https://blog.affien.com/archives/2012/07/11/bachelor-thesis-on-effective-undecidability-and-posts-problem/</guid><description>&lt;p&gt;&lt;a href="http://westerbaan.name/~bas/math/bachelor.pdf" title="On effective undecidability and Post's problem"&gt;This is my bachelor thesis on effective undecidability and Post’s problem.&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Henk Westerbaan</title><link>https://blog.affien.com/archives/2012/06/09/henk-westerbaan/</link><pubDate>Sat, 09 Jun 2012 15:45:03 +0100</pubDate><guid>https://blog.affien.com/archives/2012/06/09/henk-westerbaan/</guid><description>&lt;p&gt;&lt;a href="http://henk.westerbaan.name"&gt;&lt;img src="http://w-nz.com/~bas/images/rouwkaart-henk.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Could not open audio device for playback. with GStreamer on Rapsberry Pi</title><link>https://blog.affien.com/archives/2012/05/13/could-not-open-audio-device-for-playback-with-gstreamer-on-rapsberry-pi/</link><pubDate>Sun, 13 May 2012 15:17:23 +0100</pubDate><guid>https://blog.affien.com/archives/2012/05/13/could-not-open-audio-device-for-playback-with-gstreamer-on-rapsberry-pi/</guid><description>&lt;p&gt;You can fix this error by explicitly setting the default audio device. For instance, put this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;pcm.!default {&lt;br/&gt;
 type hw&lt;br/&gt;
 card 0&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ctl.!default {&lt;br&gt;
 type hw&lt;br&gt;
 card 0&lt;br&gt;
}&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;in &lt;code&gt;$HOME/.asoundrc&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Split ape/flac with cue into oggs on Linux</title><link>https://blog.affien.com/archives/2011/10/08/split-apeflac-with-cue-into-oggs-on-linux/</link><pubDate>Sat, 08 Oct 2011 15:56:02 +0100</pubDate><guid>https://blog.affien.com/archives/2011/10/08/split-apeflac-with-cue-into-oggs-on-linux/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&lt;strong&gt;$&lt;/strong&gt; shnsplit -o 'cust ext=ogg oggenc - -o %f' \&lt;br/&gt;
  -f CDImage.cue -t &amp;quot;%n.%p - %a - %t&amp;quot; \&lt;br/&gt;
  CDImage.ape&lt;br/&gt;
&lt;strong&gt;$&lt;/strong&gt; cuetag CDImage.cue *.ogg&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you’re on Ubuntu, you’ll need to install &lt;code&gt;cuetools&lt;/code&gt; and &lt;code&gt;shntool&lt;/code&gt;. To split &lt;code&gt;ape&lt;/code&gt;, compile and install &lt;a href="http://etree.org/shnutils/shntool/support/formats/ape/unix/3.99-u4-b5-s7/mac-3.99-u4-b5-s7.tar.gz"&gt;this port&lt;/a&gt; of &lt;code&gt;mac&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Radboud Universiteit Nieuws</title><link>https://blog.affien.com/archives/2011/06/06/radboud-universiteit-nieuws/</link><pubDate>Mon, 06 Jun 2011 15:50:24 +0100</pubDate><guid>https://blog.affien.com/archives/2011/06/06/radboud-universiteit-nieuws/</guid><description>&lt;p&gt;De Radboud Universiteit censuurt onder het mom van &lt;a href="http://www.ru.nl/actueel/nieuws-0/?ActItmIdt=811729&amp;amp;ActLbl=nieuwsplatform"&gt;een duidelijke scheiding tussen intern en extern nieuws&lt;/a&gt; sinds kort het niet-meer-onafhankelijke blad de &lt;a href="http://voxlog.nl"&gt;Vox&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Gelukkig kunt u het nieuws alsnog lezen op &lt;a href="http://runieuws.nl"&gt;RU Nieuws&lt;/a&gt;. Op deze site wordt al het interne nieuws gelekt.&lt;/p&gt;</description></item><item><title>Bertha: no-nonsense blob storage</title><link>https://blog.affien.com/archives/2011/06/04/bertha-no-nonsense-blob-storage/</link><pubDate>Sat, 04 Jun 2011 11:53:43 +0100</pubDate><guid>https://blog.affien.com/archives/2011/06/04/bertha-no-nonsense-blob-storage/</guid><description>&lt;p&gt;For a project I need to store blobs of data (~10MB) and access them over TCP. I don’t need any features like removing, updating, authentication, statistics or replication: it’s simply not required or already handled by some other part of the project.&lt;/p&gt;
&lt;p&gt;I only want to be able to store a blob and receive a key for it; retrieve a blob by its key and list all keys of the blobs stored.&lt;/p&gt;
&lt;p&gt;I couldn’t find anything that fit it. Thus I created &lt;a href="http://github.com/bwesterb/berthad"&gt;bertha&lt;/a&gt;. Lets delve right into it, shall we:&lt;/p&gt;
&lt;p&gt;To run the &lt;a href="http://github.com/bwesterb/berthad"&gt;server&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;./berthad-vfs 0.0.0.0 1234 tmp data&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s a &lt;a href="http://github.com/bwesterb/py-bertha"&gt;python client&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from bertha import BerthaClient&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; c = BerthaClient('serf', 1234)&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; list(c.list())&lt;br/&gt;
[]&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; key = c.put_str('Hello world')&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; key&lt;br/&gt;
'64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c'&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; c.get(key).read()&lt;br/&gt;
'Hello world'&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; list(c.list())&lt;br/&gt;
['64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c']&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; ctx = c.put()&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; ctx.f.write(&amp;quot;Do some&amp;quot;)&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; ctx.f.write(&amp;quot;Streaming&amp;quot;)&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; ctx.finish()&lt;br/&gt;
'975001fb9bdc0f72a78ca6326c55af86348d4c84da7ba47b7ed785a03f6803b0'&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; c.get('975001fb9bdc0f72a78ca6326c55af86348d4c84da7ba47b7ed785a03f6803b0').read()&lt;br/&gt;
'Do someStreaming'&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which also install a &lt;code&gt;bertha&lt;/code&gt; commandline tool:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;$ bertha list&lt;br/&gt;
975001fb9bdc0f72a78ca6326c55af86348d4c84da7ba47b7ed785a03f6803b0&lt;br/&gt;
64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c&lt;br/&gt;
$ bertha get 975001fb9bdc0f72a78ca6326c55af86348d4c84da7ba47b7ed785a03f6803b0&lt;br/&gt;
Do someStreaming&lt;br/&gt;
$ echo Hi | bertha put&lt;br/&gt;
c01a4cfa25cb895cdd0bb25181ba9c1622e93895a6de6f533a7299f70d6b0cfb&lt;br/&gt;
$ bertha get c01a4cfa25cb895cdd0bb25181ba9c1622e93895a6de6f533a7299f70d6b0cfb tmp&lt;br/&gt;
$ cat tmp&lt;br/&gt;
Hi&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;berthad&lt;/code&gt; code is pretty small: at the moment under a thousand lines of C with lots of comments. &lt;code&gt;GET&lt;/code&gt;s are pretty fast: &lt;code&gt;berthad&lt;/code&gt; uses Linux’ &lt;code&gt;splice&lt;/code&gt; syscall, which usually makes the network card read directly from the buffer the harddisk wrote to.&lt;/p&gt;</description></item><item><title>Lion display settings refresh-rate bug</title><link>https://blog.affien.com/archives/2011/04/30/lion-display-settings-refresh-rate-bug/</link><pubDate>Sat, 30 Apr 2011 18:36:35 +0100</pubDate><guid>https://blog.affien.com/archives/2011/04/30/lion-display-settings-refresh-rate-bug/</guid><description>&lt;p&gt;When I try to set the displaymode of my external monitor to 1024×768@60 the preferences application doesn’t listen properly and sets it to 1024×768@120, which my monitor does not support. This seems to be a bug in the developer preview.&lt;/p&gt;
&lt;p&gt;To remedy this bug, I wrote a simple commandline tool to set displaymodes in Mac OS X. It’s &lt;a href="http://github.com/bwesterb/displays"&gt;on github&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>802.1X configuration profile on Lion (Mac OS X 10.7)</title><link>https://blog.affien.com/archives/2011/03/16/802-1x-configuration-profile-on-lion-mac-os-x-10-7/</link><pubDate>Wed, 16 Mar 2011 14:24:59 +0100</pubDate><guid>https://blog.affien.com/archives/2011/03/16/802-1x-configuration-profile-on-lion-mac-os-x-10-7/</guid><description>&lt;p&gt;On the developer preview of Lion, the “+” button for 802.1X profiles was removed.&lt;/p&gt;
&lt;p&gt;You can use the iPhoneConfigurationUtility application (Google for it) to create a mobile configuration profile with the 802.1X settings, that also imports perfectly fine on Lion.&lt;/p&gt;</description></item><item><title>MacPorts on Lion (Mac OS X 10.7)</title><link>https://blog.affien.com/archives/2011/03/10/macports-on-lion-mac-os-x-10-7/</link><pubDate>Thu, 10 Mar 2011 22:40:17 +0100</pubDate><guid>https://blog.affien.com/archives/2011/03/10/macports-on-lion-mac-os-x-10-7/</guid><description>&lt;p&gt;Simply &lt;a href="http://guide.macports.org/#installing.macports.subversion"&gt;install from Subversion&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Thoughts on Flash</title><link>https://blog.affien.com/archives/2010/04/29/thoughts-on-flash/</link><pubDate>Thu, 29 Apr 2010 17:40:45 +0100</pubDate><guid>https://blog.affien.com/archives/2010/04/29/thoughts-on-flash/</guid><description>&lt;p&gt;I have some remarks on Steve Jobs’s &lt;a href="http://www.apple.com/hotnews/thoughts-on-flash/?loc=interstitialskip"&gt;“Thoughts on Flash”&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;“Adobe claims that we are a closed system, and that Flash is open, but in fact the opposite is true.”&lt;/strong&gt;. I agree with Steve: Flash is pretty closed. However, the iP(hone/od/ad) isn’t open either.
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;H.264&lt;/strong&gt;, which Jobs touts as a great modern replacement of flash, is patented. You have to pay whatever the &lt;a href="http://en.wikipedia.org/wiki/MPEG_LA"&gt;MPEG LA&lt;/a&gt; fancies you to pay for use of the standard. This is not really different from the control of Adobe over Flash.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;iPhone OS&lt;/strong&gt; is closed. You need to buy yourself into the iPhone Development Program. Again Apple can shut the program down whenever they like, which is not really different from the control of Adobe over Flash development.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safari is an intermediate layer and creates sub-standard apps.&lt;/strong&gt; Jobs claims that third-party intermediate layers result in sub-standard apps. Jobs argues that an intermediate layer will keep developers from platform enhancements, won’t result in targeted great apps and won’t put apps directly on the shoulder of the platform. If he is thinking about Safari, he is right: web-apps for the iPhone just don’t feel great, can’t use all the platform enhancements and don’t result in great targeted apps.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Looking for an apartment</title><link>https://blog.affien.com/archives/2010/02/28/looking-for-an-apartment/</link><pubDate>Sun, 28 Feb 2010 01:54:30 +0100</pubDate><guid>https://blog.affien.com/archives/2010/02/28/looking-for-an-apartment/</guid><description>&lt;p&gt;Dear readers,&lt;/p&gt;
&lt;p&gt;I’m looking for an apartment in the neighborhood of Nijmegen. I’m not picky, but can’t afford more than €300,- in total per month.&lt;/p&gt;
&lt;p&gt;Contact me per e-mail (bas@&lt;em&gt;this domain&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Bas&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; I’m settled!&lt;/p&gt;</description></item><item><title>Dutch student protest</title><link>https://blog.affien.com/archives/2010/01/31/dutch-student-protest/</link><pubDate>Sun, 31 Jan 2010 14:08:35 +0100</pubDate><guid>https://blog.affien.com/archives/2010/01/31/dutch-student-protest/</guid><description>&lt;p&gt;This week, various student organisations protest against major cuts in the funding of education and research.&lt;/p&gt;
&lt;p&gt;A reader of dutch, can visit &lt;a href="http://studentendemonstratie.nl/nijmegen"&gt;their site&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Unique followers on Twitter</title><link>https://blog.affien.com/archives/2009/12/16/unique-followers-on-twitter/</link><pubDate>Wed, 16 Dec 2009 19:27:12 +0100</pubDate><guid>https://blog.affien.com/archives/2009/12/16/unique-followers-on-twitter/</guid><description>&lt;p&gt;As &lt;a href="http://corethinking.com/2009/12/13/how-twitters-new-lists-feature-will-dramatically-impact-follower-count/"&gt;pointed out by Jorg Kennis&lt;/a&gt;, &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;‘s new lists feature make it hard to determine the amount of unique followers. I’ve written a simple script, using a slightly modified &lt;a href="http://joshthecoder.github.com/tweepy/"&gt;TweePy&lt;/a&gt;, to determine the amount of unique followers.&lt;/p&gt;
&lt;p&gt;Example usage:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;bas@w-nz ~/twitter-unique-followers $ python twitter-unique-followers.py JorgK -ubwesterb&lt;br/&gt;
Password:&lt;br/&gt;
rate_limit_status: remaining_hits: 112&lt;br/&gt;
Jorg Kennis&lt;br/&gt;
 followed directly by 182&lt;br/&gt;
 in lists&lt;br/&gt;
  RPtje/vriendenbekenden subscribed to by 0&lt;br/&gt;
  JorgK/TechNL subscribed to by 0&lt;br/&gt;
  sentfanwyaerda/nijmegen1 subscribed to by 9&lt;br/&gt;
  JorgK/Friends subscribed to by 0&lt;br/&gt;
  sjorsjes/Community subscribed to by 0&lt;br/&gt;
  robinspeijer/iPhone subscribed to by 1&lt;br/&gt;
  nielsschooneman/iPhone subscribed to by 0&lt;br/&gt;
  JeanPaulH/iPhoneclub subscribed to by 5&lt;br/&gt;
number of unique followers: 198&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can download it &lt;a href="http://affien.com/~bas/projects/twitter-unique-followers.zip"&gt;here&lt;/a&gt;. I could write a simple webpage with the same functionality, if anyone would mind.&lt;/p&gt;</description></item><item><title>Normul</title><link>https://blog.affien.com/archives/2009/11/01/normul/</link><pubDate>Sun, 01 Nov 2009 12:18:03 +0100</pubDate><guid>https://blog.affien.com/archives/2009/11/01/normul/</guid><description>&lt;p&gt;Normul normalizes URLs. It expands shortened URLs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from normul import normul&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; normul('http://bit.ly/1I4VQ')&lt;br/&gt;
{'type': 'other', 'normalized': 'http://www.shinguz.ch/MySQL/mysql_mv.html', 'original': 'http://bit.ly/1I4VQ'}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And shows useful links for hosted-images:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; normul('http://yfrog.com/6c5krj')&lt;br/&gt;
{'image': {'full': 'http://img228.imageshack.us/img228/1079/5kr.jpg', 'thumbnail': 'http://img228.imageshack.us/img228/1079/5kr.th.jpg'}, 'type': 'image', 'original': 'http://yfrog.com/6c5krj', 'normalized': 'http://yfrog.com/6c5krj'}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can find the simple but convenient sourcecode &lt;a href="http://w-nz.com/cgi-bin/gitweb.cgi?p=normul.git;a=summary"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Cantor never bores (1)</title><link>https://blog.affien.com/archives/2009/10/24/cantor-never-bores-1/</link><pubDate>Sat, 24 Oct 2009 21:11:23 +0100</pubDate><guid>https://blog.affien.com/archives/2009/10/24/cantor-never-bores-1/</guid><description>&lt;p&gt;Given a set of &lt;a href="http://en.wikipedia.org/wiki/Countable"&gt;countable&lt;/a&gt; sets &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;, such that &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is &lt;a href="http://en.wikipedia.org/wiki/Total_order"&gt;totally ordered&lt;/a&gt; by inclusion, videlicet for every &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;A,B\in K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; either &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;⊆&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;A\subseteq B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; or &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;⊇&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;A\supseteq B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;. Intuitively, for at every step in this chain one element at least must be added, one expects the set &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; to be countable as well.&lt;/p&gt;
&lt;p&gt;Suppose &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is countable. Then the union, &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;⋃&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\bigcup K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is a countable union of countable sets, hence countable. (Suppose &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi mathvariant="double-struck"&gt;N&lt;/mi&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;k: \mathbb N \to K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is an enumeration of &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; and &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi mathvariant="double-struck"&gt;N&lt;/mi&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;f_i: \mathbb N \to k(i)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; enumerations of the elements of the chain. Then &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;mo separator="true"&gt;,&lt;/mo&gt;&lt;mo&gt;…&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;f_0(0), f_1(0), f_0(1), f_2(0), f_1(1), f_0(2), \ldots&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; enumerates &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;⋃&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\bigcup K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;.)&lt;/p&gt;
&lt;p&gt;Thus &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;⋃&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\bigcup K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is an &lt;a href="http://en.wikipedia.org/wiki/Upper_bound"&gt;upper bound&lt;/a&gt; of &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;. In the &lt;a href="http://en.wikipedia.org/wiki/Partially_ordered_set"&gt;poset&lt;/a&gt; of countable subsets of some set &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;U&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;, of which &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;⋃&lt;/mo&gt;&lt;mi&gt;K&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\bigcup K&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is a subset, every non-empty chain has an upper bound. Hence, using &lt;a href="http://en.wikipedia.org/wiki/Zorn%27s_lemma"&gt;Zorn’s lemma&lt;/a&gt; there is a &lt;a href="http://en.wikipedia.org/wiki/Maximal_element"&gt;maximal element&lt;/a&gt;, say &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;M&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Suppose &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;U&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is uncountable, then there exists a &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;⋆&lt;/mo&gt;&lt;mo&gt;∈&lt;/mo&gt;&lt;mi&gt;U&lt;/mi&gt;&lt;mi mathvariant="normal"&gt;\&lt;/mi&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\star \in U \backslash M&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;. &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;mo&gt;∪&lt;/mo&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;mo&gt;⋆&lt;/mo&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;M \cup \{\star\}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is most definitely also countable and &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;mo&gt;⊂&lt;/mo&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;mo&gt;∪&lt;/mo&gt;&lt;mo stretchy="false"&gt;{&lt;/mo&gt;&lt;mo&gt;⋆&lt;/mo&gt;&lt;mo stretchy="false"&gt;}&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;M \subset M \cup \{\star\}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; which contradicts &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;M&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;’s maximality. We are forced to conclude that there exists an uncountable chain of countable sets.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Georg_Cantor#Set_theory"&gt;Cantor’s set theory&lt;/a&gt; keeps surprising.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt;: an example of such a chain is the set of the countable &lt;a href="http://en.wikipedia.org/wiki/Ordinal_number"&gt;ordinals&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Another update&lt;/ins&gt;: a “more concrete” example are the downsets in &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant="double-struck"&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\mathbb Q&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; without the empty set and &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant="double-struck"&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\mathbb Q&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; itself. These downsets correspond to real numbers, see &lt;a href="http://en.wikipedia.org/wiki/Dedekind_cut"&gt;Dedekind Cuts&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Bond against Loanwords</title><link>https://blog.affien.com/archives/2009/09/10/bond-against-loanwords/</link><pubDate>Thu, 10 Sep 2009 00:37:14 +0100</pubDate><guid>https://blog.affien.com/archives/2009/09/10/bond-against-loanwords/</guid><description>&lt;p&gt;Although I don’t bear any animosity against most dutch loanwords (except those Anglo-Saxon), the dictionary of the dutch &lt;a href="http://www.geocities.com/SoHo/Den/7522/Index.html"&gt;Bond tegen Leenwoorden&lt;/a&gt; is a true joy to read.&lt;/p&gt;</description></item><item><title>21</title><link>https://blog.affien.com/archives/2009/08/31/21/</link><pubDate>Mon, 31 Aug 2009 11:18:48 +0100</pubDate><guid>https://blog.affien.com/archives/2009/08/31/21/</guid><description>&lt;p&gt;Since yesterday I, for the first time, enjoy the anything-but-special age of 21 years.&lt;/p&gt;</description></item><item><title>Windows 7 Sins</title><link>https://blog.affien.com/archives/2009/08/27/windows-7-sins/</link><pubDate>Thu, 27 Aug 2009 14:06:16 +0100</pubDate><guid>https://blog.affien.com/archives/2009/08/27/windows-7-sins/</guid><description>&lt;p&gt;&lt;a href="http://windows7sins.org/"&gt;Windows 7 Sins&lt;/a&gt;. I strongly agree with points 1, 3, 4, 5 and 6. The arguments for points 2 and 7 are a bit weak, but I do agree with the conclusions.&lt;/p&gt;
&lt;p&gt;For the non US audience, it would have been nice to note that if Microsoft (or the US) would recall all foreign licenses for Windows, our entire government is crippled.&lt;/p&gt;</description></item><item><title>Twitter and Facebook</title><link>https://blog.affien.com/archives/2009/08/07/twitter-and-facebook/</link><pubDate>Fri, 07 Aug 2009 00:46:19 +0100</pubDate><guid>https://blog.affien.com/archives/2009/08/07/twitter-and-facebook/</guid><description>&lt;p&gt;were both victim of a DDoS today. Silently, I always hoped that a really long-lasting one will convince them to put effort in a distributed scheme.&lt;/p&gt;
&lt;p&gt;Maybe I should be waiting for another &lt;a href="http://wave.google.com/"&gt;Wave&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>PijsMarietje</title><link>https://blog.affien.com/archives/2009/07/01/pijsmarietje/</link><pubDate>Wed, 01 Jul 2009 16:58:44 +0100</pubDate><guid>https://blog.affien.com/archives/2009/07/01/pijsmarietje/</guid><description>&lt;p&gt;At the faculty for sciences there are canteens for students. In each of these, there’s sound equipment connected to linux boxes. On each of those linux boxes, we run a music-request-server called &lt;em&gt;Marietje&lt;/em&gt;. I just finished writing a front-end in Javascript. It wasn’t a pain. As instead, the use of &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; was a bliss.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://zuidslet.science.ru.nl:8080/"&gt;The frontend for one of those boxes&lt;/a&gt; and &lt;a href="http://w-nz.com/cgi-bin/gitweb.cgi?p=maried.git;a=summary"&gt;the source code&lt;/a&gt; (see the &lt;code&gt;ajax&lt;/code&gt; folder).&lt;/p&gt;</description></item><item><title>Damned DOM (1)</title><link>https://blog.affien.com/archives/2009/06/22/damned-dom-1/</link><pubDate>Mon, 22 Jun 2009 15:34:51 +0100</pubDate><guid>https://blog.affien.com/archives/2009/06/22/damned-dom-1/</guid><description>&lt;p&gt;When I wanted to react to any changes to a &lt;code&gt;input&lt;/code&gt; textbox immediately, my first instrinct was to use &lt;code&gt;onChange&lt;/code&gt;. &lt;code&gt;onChange&lt;/code&gt;, however, is called when the &lt;code&gt;input&lt;/code&gt; loses focus. &lt;code&gt;onKeyPress&lt;/code&gt; then? Isn’t called on backspaces. &lt;code&gt;onKeyDown&lt;/code&gt;, maybe? It does get called, but the effect of the keystroke isn’t yet applied, for the return value determines whether it that is done in the first place. (Same story for &lt;code&gt;onKeyPress&lt;/code&gt; by the way.) &lt;code&gt;onKeyUp&lt;/code&gt; does work a bit, except if someone is holding down a single key, for a while.&lt;/p&gt;
&lt;p&gt;The solution: hook &lt;code&gt;onKeyUp&lt;/code&gt; and use &lt;code&gt;setTimeout&lt;/code&gt; with a timeout of 0. Yugh. I hate DOM.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;ins&gt;Big Fat Disclaimer&lt;/ins&gt;: I actually tested this only on one browser.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Unicode to ASCII (1)</title><link>https://blog.affien.com/archives/2009/06/19/unicode-to-ascii-1/</link><pubDate>Fri, 19 Jun 2009 14:19:10 +0100</pubDate><guid>https://blog.affien.com/archives/2009/06/19/unicode-to-ascii-1/</guid><description>&lt;p&gt;When I want to generate usernames from real names, which can contain non-ascii characters, you can’t simply ignore the unicode characters. For instance, danielle@blaat.org is the right e-mail address for Daniëlle, danille@blaat.org isn’t.&lt;/p&gt;
&lt;p&gt;There’s trick. Unicode has got a single code for ë itself, but it has also got a code which (simplified) adds ¨ on top of the previous character. The unicode standard defines a normal form in which (at least) all such characters, which can be, are represented using such modifiers. If you then simply ignore the non-ascii representable codes, you’ll get the desired result.&lt;/p&gt;
&lt;p&gt;In python: &lt;code&gt;unicodedata.normalize('NFKD', txt).encode('ASCII', 'ignore')&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, this isn’t &lt;em&gt;the&lt;/em&gt; right solution. For instance, in german, one prefers ue as a replacement of ü over u.&lt;/p&gt;</description></item><item><title>Django annoyances: no reverse select_related</title><link>https://blog.affien.com/archives/2009/05/30/django-annoyances-no-reverse-select_related/</link><pubDate>Sat, 30 May 2009 14:48:45 +0100</pubDate><guid>https://blog.affien.com/archives/2009/05/30/django-annoyances-no-reverse-select_related/</guid><description>&lt;p&gt;Consider&lt;/p&gt;
&lt;p&gt;&lt;code&gt;for page in Page.objects.all():&lt;br/&gt;
  print page.title&lt;br/&gt;
  for comment in page.comments.all():&lt;br/&gt;
    print comment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There will be a single query to fetch all pages, but there will be for every page another query to fetch its comments. Luckily, Django has got a nice trick up its sleave: &lt;code&gt;select_related&lt;/code&gt;. Would I use instead of &lt;code&gt;Page.objects.all()&lt;/code&gt;, &lt;code&gt;Page.objects.select_related('comments').all()&lt;/code&gt; then Django will use a single joined query to prefetch comments for each page.&lt;/p&gt;
&lt;p&gt;However, Django’s &lt;code&gt;select_related&lt;/code&gt; only supports forward one-to-many references. No many-to-many; certainly no reverce many-to-many; no reverse one-to-many and no, not even reverse one-to-one (&lt;a href="http://code.djangoproject.com/ticket/7270"&gt;yet&lt;/a&gt;). &lt;a href="http://code.djangoproject.com/ticket/2238"&gt;A developer&lt;/a&gt; claims it’s impossible (which is bullshit), &lt;a href="http://code.djangoproject.com/ticket/9166"&gt;another&lt;/a&gt; asks for patches, which means he doesn’t care doing it himself.&lt;/p&gt;
&lt;p&gt;It’s quite easy to manually code around the missing reverse &lt;code&gt;select_related&lt;/code&gt;, but it takes too many ugly lines compared to the single word it could’ve been.&lt;/p&gt;</description></item><item><title>Javascript’s stupid Date constructor</title><link>https://blog.affien.com/archives/2009/04/29/javascripts-stupid-date-constructor/</link><pubDate>Wed, 29 Apr 2009 17:27:42 +0100</pubDate><guid>https://blog.affien.com/archives/2009/04/29/javascripts-stupid-date-constructor/</guid><description>&lt;p&gt;&lt;code&gt;new Date(2009, 1, 1)&lt;/code&gt; represents the first of February 2009. Not the second of February nor the first of January. Why this stupidity?&lt;/p&gt;</description></item><item><title>GStreamer: accurate duration</title><link>https://blog.affien.com/archives/2009/04/19/gstreamer-accurate-duration/</link><pubDate>Sun, 19 Apr 2009 14:26:01 +0100</pubDate><guid>https://blog.affien.com/archives/2009/04/19/gstreamer-accurate-duration/</guid><description>&lt;p&gt;When decoding, for instance, a variable-bitrate MP3, gstreamer reported durations are, to say the least, estimates. I’ve tried to get a better result in a few ways. First off, some files yield a &lt;code&gt;duration&lt;/code&gt; tag, but even if you’re lucky and it is there, there are no guaranties about precision. After that I tried seeking to the end (&lt;code&gt;GST_SEEK_END&lt;/code&gt;) of the stream and querying the position, which gstreamer didn’t like. Finally, routing the audio into a &lt;code&gt;fakesink&lt;/code&gt;, waiting for the end of stream and then querying for the position gives the right result. It’s not the prettiest method, but it works.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.affien.com/wp-content/uploads/2009/04/gst-duration.py"&gt;This&lt;/a&gt; is a Python script that prints the duration of a media to stdout.&lt;/p&gt;</description></item><item><title>Spacing up- and downarrow properly for up- and downsets</title><link>https://blog.affien.com/archives/2009/03/24/spacing-up-and-downarrow-properly-for-up-and-downsets/</link><pubDate>Tue, 24 Mar 2009 23:34:44 +0100</pubDate><guid>https://blog.affien.com/archives/2009/03/24/spacing-up-and-downarrow-properly-for-up-and-downsets/</guid><description>&lt;p&gt;&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mo&gt;↑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;f(\uparrow x)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is ugly, but &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy="false"&gt;(&lt;/mo&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;↑&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;mo stretchy="false"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;f(\left\uparrow x\right.)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is nice! The solution: prefix &lt;code&gt;\uparrow&lt;/code&gt; with &lt;code&gt;\mathopen&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Fosdem (3)</title><link>https://blog.affien.com/archives/2009/02/06/fosdem-3/</link><pubDate>Fri, 06 Feb 2009 13:57:29 +0100</pubDate><guid>https://blog.affien.com/archives/2009/02/06/fosdem-3/</guid><description>&lt;p&gt;In a few hours I’ll travel the short distance to Bruxelles to visit Fosdem. Once again I’m pretty excited :). Lets hope this time the pink elephants of the Delirium Cafe don’t crush me. If you’re also going, drop me a comment.&lt;/p&gt;</description></item><item><title>Timestamp 1234567890</title><link>https://blog.affien.com/archives/2009/01/29/timestamp-1234567890/</link><pubDate>Thu, 29 Jan 2009 23:37:42 +0100</pubDate><guid>https://blog.affien.com/archives/2009/01/29/timestamp-1234567890/</guid><description>&lt;p&gt;It’s soon. The 14th of februari, 00:31:30 (Europe/Amsterdam). Will the world end? Will ancient libc code giggle and break?&lt;/p&gt;</description></item><item><title>Aperitif for order</title><link>https://blog.affien.com/archives/2009/01/01/aperitif-for-order/</link><pubDate>Thu, 01 Jan 2009 02:16:09 +0100</pubDate><guid>https://blog.affien.com/archives/2009/01/01/aperitif-for-order/</guid><description>&lt;p&gt;Assign 1 to True and 0 to False. Now the minimum corresponds to “and” and maximum to “or”. If you give it a bit more though, less or equal to corresponds to implication. This is a lot more general than this specific case. Add .5 for a third value (eg. NULL) and it still yields natural results.&lt;/p&gt;
&lt;p&gt;We can recognize the behaviour of minima and maxima in a lot of other things. Take for instance set inclusion as order with intersection as minimum and union as maximum. Actually, the link between general order and set inclusion is frequently made to then propose that “intersection of two set of cases” and “logical and” do look a lot alike.&lt;/p&gt;
&lt;p&gt;This is just the tip of the huge iceberg. Order appears everywhere! Everywhere in Math. Everywhere in CS. And its just recognizing simple order I’ve demonstrated. Other useful concepts in order theory that I didn’t even touch are Galois Connections and formal concept analysis.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Oh, another&lt;/ins&gt; example of an order are integers with bitwise or and bitwise and. It is left as an exercise to the reader when one integer is greater than another.&lt;/p&gt;
&lt;p&gt;Interested? Buy &lt;a href="http://www.cambridge.org/uk/catalogue/catalogue.asp?isbn=0521784514"&gt;an Introduction to Lattices and Order&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>2009</title><link>https://blog.affien.com/archives/2009/01/01/2009/</link><pubDate>Thu, 01 Jan 2009 00:41:53 +0100</pubDate><guid>https://blog.affien.com/archives/2009/01/01/2009/</guid><description>&lt;p&gt;Happy Newyear!&lt;/p&gt;</description></item><item><title>On-demand singleton for Python</title><link>https://blog.affien.com/archives/2008/12/27/on-demand-singleton-for-python/</link><pubDate>Sat, 27 Dec 2008 20:28:33 +0100</pubDate><guid>https://blog.affien.com/archives/2008/12/27/on-demand-singleton-for-python/</guid><description>&lt;p&gt;Some singletons eat slightly more resources, than you want to give them for free. For instance, if you have a home-brew threadpool singleton, you don’t want it to create its threads if you are not going to use it. The solution: &lt;a href="http://blog.affien.com/wp-content/uploads/2008/12/runtime.py"&gt;a simple function&lt;/a&gt; that creates a stub which proxies attribute access to an ad-hoc created instance.&lt;/p&gt;
&lt;p&gt;Usage: &lt;code&gt;create_ondemand_singleton('mylibrary.Threadpool', MyThreadPoolClass)&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>The Cuckoo Hashtable</title><link>https://blog.affien.com/archives/2008/12/21/the-cuckoo-hashtable/</link><pubDate>Sun, 21 Dec 2008 23:22:41 +0100</pubDate><guid>https://blog.affien.com/archives/2008/12/21/the-cuckoo-hashtable/</guid><description>&lt;p&gt;A Hashtable algorithm is a specific algorithm to implement key-value pair datastructure with efficient by-key look-ups using hashing of the keys. A hashtable contains a list of buckets. In a simple implementation, the i-th bucket, contains the key-value pairs in a list of which the key has a hash that is i modulo the amount of buckets. The hash-table would increase the amount of buckets if any bucket contains more than a fixed amount of pairs. This results in a constant-time look-up, but an insertion might invoke a expensive rebuild.&lt;/p&gt;
&lt;p&gt;There are a few variations on Hash Tables. I’d like to share a really smart one: &lt;strong&gt;the Cuckoo Hashtable&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Cuckoo_hashing"&gt;Cuckoo hashtable&lt;/a&gt; expects two different hash-functions for the keys. Instead of storing a list of pairs in each bucket, the Cuckoo Hash table stores a single pair in each bucket. When inserting a pair, it is inserted in one of the two possible locations. If it happens to be occupied, the old pair is replaced. Then the replaced pair is inserted at its other possible location, potentially kicking out another pair. This step is repeated, until there is no displaced pair or a loop is detected. When a loop is detected, the hash-functions can be changed, if the buckets are for the most part empty -or- when the table is almost full, the amount of buckets can be increased. It can be shown that an insertion has a amortized constant time. (The buckets can be resized in-place, and each entry is repositioned as if it was displaced by another.)&lt;/p&gt;</description></item><item><title>If I’d own a botnet… (1)</title><link>https://blog.affien.com/archives/2008/11/26/if-id-own-a-botnet-1/</link><pubDate>Wed, 26 Nov 2008 22:36:47 +0100</pubDate><guid>https://blog.affien.com/archives/2008/11/26/if-id-own-a-botnet-1/</guid><description>&lt;p&gt;…and didn’t want to loose it if my control servers got shut down, I’d let every orphaned zombie randomly connect to hosts in a given IP range, and challenge them to give a preimage of a hardcoded hash. [ detail: add a salt to prevent replay attacks ]. With a sufficiently safe casu quo large range, it also might be helpfull to allow zombies to forward still orphan zombies.&lt;/p&gt;</description></item><item><title>Music Animation Machine</title><link>https://blog.affien.com/archives/2008/10/10/music-animation-machine/</link><pubDate>Fri, 10 Oct 2008 20:34:57 +0100</pubDate><guid>https://blog.affien.com/archives/2008/10/10/music-animation-machine/</guid><description>&lt;p&gt;The sound and performance really aren’t that good, but the visual connection is so powerful:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=pVadl4ocX0M"&gt;Bach’s little fuge on a Music Animation Machine&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Vim Essentials</title><link>https://blog.affien.com/archives/2008/09/19/vim-essentials/</link><pubDate>Fri, 19 Sep 2008 08:40:54 +0100</pubDate><guid>https://blog.affien.com/archives/2008/09/19/vim-essentials/</guid><description>&lt;p&gt;&lt;a href="http://www.semicomplete.com/presentations/vim"&gt;Vim Essentials&lt;/a&gt;. Usefull.&lt;/p&gt;</description></item><item><title>20</title><link>https://blog.affien.com/archives/2008/08/31/20/</link><pubDate>Sun, 31 Aug 2008 18:43:58 +0100</pubDate><guid>https://blog.affien.com/archives/2008/08/31/20/</guid><description>&lt;p&gt;Yesterday we turned 20. I’ll miss that one.&lt;/p&gt;</description></item><item><title>Wacken (2)</title><link>https://blog.affien.com/archives/2008/07/26/wacken-2/</link><pubDate>Sat, 26 Jul 2008 14:04:57 +0100</pubDate><guid>https://blog.affien.com/archives/2008/07/26/wacken-2/</guid><description>&lt;p&gt;Tomorrow morning, way too early, I’ll be leaving for the picturesque town of Wacken in the north of Germany to attend the &lt;a href="http://wacken.com/"&gt;Wacken Open Air&lt;/a&gt; festival. I’ll probably be back the third of august and recovered the fourth.&lt;/p&gt;</description></item><item><title>iPhone WiFi weirdness</title><link>https://blog.affien.com/archives/2008/07/22/iphone-wifi-weirdness/</link><pubDate>Tue, 22 Jul 2008 18:32:44 +0100</pubDate><guid>https://blog.affien.com/archives/2008/07/22/iphone-wifi-weirdness/</guid><description>&lt;p&gt;I’m having trouble with the wireless on my 3G iPhone. Either an action works perfectly (for instance downloading e-mail or visiting a website), or it will just time-out. I just jailbroke it and installed sshd. ssh-ing to my it via 3G miraculously works perfectly. However, when connecting to it via WiFi it’ll simply refuse data. That is, until you let the iPhone try to get data itself by for instance visiting a website. Then suddenly the ssh packets come through again. In the background (with &lt;a href="http://www.gnu.org/software/screen/"&gt;screen&lt;/a&gt;) I’m running a very frequent ping to my local gateway which makes ssh work perfectly again via WiFi. A very unsatisfying hack.&lt;/p&gt;
&lt;p&gt;It seems like an aggressive power safe on the WiFi.&lt;/p&gt;</description></item><item><title>iPhone (0)</title><link>https://blog.affien.com/archives/2008/07/18/iphone-0/</link><pubDate>Fri, 18 Jul 2008 17:23:42 +0100</pubDate><guid>https://blog.affien.com/archives/2008/07/18/iphone-0/</guid><description>&lt;p&gt;On the day of release, I bought an iPhone. We all know the great features; thus let’s talk about the annoyances.&lt;/p&gt;
&lt;p&gt;It &lt;strong&gt;crashes&lt;/strong&gt; and gets &lt;strong&gt;sluggish&lt;/strong&gt; a lot. Especially Safari crashes a lot and the contact list at one moment took 10 seconds to get responsive. Over time random crashes in all applications appeared. Rebooting it, actually, seems to have solved it (for now).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wifi&lt;/strong&gt; is unreliable. Sitting right next to the router it’s still a game of chance whether it will load a website properly or just time-out. This often leaves me disabling Wifi, and using HSDPA instead (which is our 3G), which has a &lt;strong&gt;terrible coverage&lt;/strong&gt;. Outside reception is great, but even inside a building near a window, it only shows one or two “pips”. This again, often leaves me disabling 3G in favor of the (slower) but the more reliable GRPS (?).&lt;/p&gt;
&lt;p&gt;I use iTunes on Windows in VMWare to sync my iPhone, which works great for the music. For the other stuff, like contacts and photos it just does not work. &lt;strong&gt;Syncing&lt;/strong&gt; with google contacts or the windows address book just doesn’t work on windows. There isn’t even any support for calendar syncing for windows. I still have to look intro a free exchange compatible server. (Anyone?)&lt;/p&gt;
&lt;p&gt;T-Mobile in the Netherlands seems to have trouble with the administration of all new subscriptions. Billing information and visual voicemail still don’t work.&lt;/p&gt;
&lt;p&gt;(Nevertheless, it’s a great toy)&lt;/p&gt;</description></item><item><title>PyX</title><link>https://blog.affien.com/archives/2008/07/08/pyx/</link><pubDate>Tue, 08 Jul 2008 01:57:56 +0100</pubDate><guid>https://blog.affien.com/archives/2008/07/08/pyx/</guid><description>&lt;p&gt;The software I use to render &lt;a href="http://blog.w-nz.com/archives/2008/04/02/benchmarking-couchdb-1/"&gt;those&lt;/a&gt; &lt;a href="http://blog.w-nz.com/archives/2008/04/15/benchmarking-couchdb-2/"&gt;great&lt;/a&gt; &lt;a href="http://blog.w-nz.com/archives/2008/07/08/gits-versus-svns-storage-efficiency/"&gt;graphs&lt;/a&gt; might be of interest to some. Instead of using a clumsy GUI or an inflexible graph language, I use a Python library called &lt;a href="http://pyx.sourceforge.net/"&gt;PyX&lt;/a&gt; which is able to generate beautiful graphs. At its core it’s a generator for TeX, and rendering graphs is just one thing it does well!&lt;/p&gt;
&lt;p&gt;Take a look at the &lt;a href="http://pyx.sourceforge.net/examples/index.html"&gt;examples&lt;/a&gt; and convince yourself!&lt;/p&gt;</description></item><item><title>git‘s versus svn‘s storage efficiency</title><link>https://blog.affien.com/archives/2008/07/08/gits-versus-svns-storage-efficiency/</link><pubDate>Tue, 08 Jul 2008 01:43:47 +0100</pubDate><guid>https://blog.affien.com/archives/2008/07/08/gits-versus-svns-storage-efficiency/</guid><description>&lt;p&gt;At &lt;a href="http://codeyard.net/"&gt;Codeyard&lt;/a&gt; we maintain a git and a subversion repository (which &lt;a href="http://blog.w-nz.com/archives/2008/05/26/cyv-syncing-git-and-svn/"&gt;are synced&lt;/a&gt; with each other) for each of the &amp;gt;115 projects. The following graph shows the repositories plotted logarithmically according to the size of their whole server side subversion repository horizontally and their git repository size vertically:&lt;br&gt;
&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/07/git-vs-svn.png"&gt;&lt;img alt="" class="aligncenter size-full wp-image-320" decoding="async" height="285" loading="lazy" sizes="auto, (max-width: 428px) 100vw, 428px" src="http://blog.w-nz.com/wp-content/uploads/2008/07/git-vs-svn.png" srcset="https://blog.affien.com/wp-content/uploads/2008/07/git-vs-svn.png 428w, https://blog.affien.com/wp-content/uploads/2008/07/git-vs-svn-300x199.png 300w" title="Git versus SVN storage efficiency" width="428"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To make more sense of the logarithmic nature of the graph, I’ve added three lines. The first (solid black) indicates the points of which both sizes are equal. The second course dashed line indicates the points of which the subversion repository is twice as large as the git repository. And lastly, the third finely dashed line indicates the points of which the subversion repository is five times as large as the git repository.&lt;/p&gt;
&lt;p&gt;All projects for which git is less storage efficient, are smaller than 100Kb. The projects for which git is most storage efficient (up to even 6 times for a certain C# project), are all of medium size (10–100MB) and code-heavy. For the other projects, which are blob heavy (eg. images), git and subversion are close (git beats svn by ~20%).&lt;/p&gt;
&lt;p&gt;One notable disadvantage of &lt;em&gt;huge&lt;/em&gt; (someone committed a livecd image) git repositories, is an apparent &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;≥&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\geq2N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; memory usage of &lt;code&gt;git repack&lt;/code&gt; even if I tell it not to with &lt;code&gt;--window-memory&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>find: invalid predicate `-delete'</title><link>https://blog.affien.com/archives/2008/06/29/find-invalid-predicate-delete/</link><pubDate>Sun, 29 Jun 2008 19:30:31 +0100</pubDate><guid>https://blog.affien.com/archives/2008/06/29/find-invalid-predicate-delete/</guid><description>&lt;p&gt;Check for a stray version of &lt;code&gt;find&lt;/code&gt; in &lt;code&gt;/bin&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>“waiting for x server to begin accepting connections”</title><link>https://blog.affien.com/archives/2008/06/29/waiting-for-x-server-to-begin-accepting-connections/</link><pubDate>Sun, 29 Jun 2008 18:19:58 +0100</pubDate><guid>https://blog.affien.com/archives/2008/06/29/waiting-for-x-server-to-begin-accepting-connections/</guid><description>&lt;p&gt;Try &lt;code&gt;DisallowTCP = false&lt;/code&gt; under &lt;code&gt;[Security]&lt;/code&gt; in &lt;code&gt;/etc/X11/Sessions/Gnome/custom.conf&lt;/code&gt; or similar for other window managers. Obviously this isn’t a very desirable solution, &lt;code&gt;emerge --emptytree gnome&lt;/code&gt; might do the trick too.&lt;/p&gt;
&lt;p&gt;(and obviously this might be just one of the many underlying causes for the very generic symptom of X not accepting connections)&lt;/p&gt;</description></item><item><title>cyv: syncing git and svn</title><link>https://blog.affien.com/archives/2008/05/26/cyv-syncing-git-and-svn/</link><pubDate>Mon, 26 May 2008 23:16:06 +0100</pubDate><guid>https://blog.affien.com/archives/2008/05/26/cyv-syncing-git-and-svn/</guid><description>&lt;p&gt;For &lt;a href="http://codeyard.nl/"&gt;codeyard&lt;/a&gt; I’m developing &lt;a href="http://w-nz.com/gitweb/gitweb.cgi?p=cyv.git;a=summary"&gt;cyv&lt;/a&gt;, which is a (still quite specific) util (written in Python!) to keep svn and git repo’s in sync. On the serverside, at least. First, let me explain what exactly is synced.&lt;/p&gt;
&lt;p&gt;When someone commits to a svn repo, the git repo is synced with &lt;code&gt;git-svn&lt;/code&gt;. You can just clone the git repo and &lt;code&gt;git pull&lt;/code&gt; instead of having to use &lt;code&gt;git-svn&lt;/code&gt; yourself.&lt;/p&gt;
&lt;p&gt;When pushing commits to the git repo on a branch that came from the svn repo, the commits are &lt;code&gt;git-svn dcommit&lt;/code&gt;-ed. If it fails (svn doesn’t do merges that well), it’ll revert the updates and will receive the successful part of the dcommit on the next post-commit triggered fetch from the svn repo. The user will have to &lt;code&gt;git-pull&lt;/code&gt; and fix the commits locally: the git manner.&lt;/p&gt;
&lt;p&gt;If pushes don’t involve the svn backed branches, it won’t have any unusual side-effects. This allows for pushing and pulling of topic-branches separate from svn and pushing them, when mature enough, into subversion without ever having to hassle (as much) with &lt;code&gt;git-svn&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An obvious huge advantage is that a &lt;code&gt;git-clone&lt;/code&gt; of the git repo is a hell of a lot faster than a &lt;code&gt;git svn clone&lt;/code&gt;. A second big advantage is that someone can choose to either use git or svn himself while not mutually excluding the other. This is of special concern to codeyard, where projects should be accessible to everyone: beginners and advanced. If instead we offered fully separated git repositories, the projects that prefer git would become inaccessible for most. And if we wouldn’t offer git repos, people would set them up themselves elsewhere, for they really don’t want to bother themselves with &lt;code&gt;git-svn&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cyv&lt;/code&gt; contains some neat features. One I want to highlight is the &lt;code&gt;cyv-layout&lt;/code&gt; file, you can place in the root of the svn repo. It tells &lt;code&gt;cyv&lt;/code&gt; how the repository is laid out. Eg:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;trunk:trunk&lt;br/&gt;
branches/*: branches/*&lt;br/&gt;
tags/*: releases/*&lt;br/&gt;
some-git-branch: some/path/in/the/svn/repo&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Another one is a wrapper around &lt;code&gt;git-shell&lt;/code&gt; to have per repository permissions for different users depending on their ssh pub key.&lt;/p&gt;
&lt;p&gt;To reiterate, &lt;code&gt;cyv&lt;/code&gt; is still quite specific to the needs of codeyard. (If you’re a codeyard participant: be patient, it’ll be up mid june). However, if you’re interested, I’ll be glad to hear from you.&lt;/p&gt;</description></item><item><title>Don’t forget /etc/init.d/hibernate-cleanup</title><link>https://blog.affien.com/archives/2008/05/23/dont-forget-etcinitdhibernate-cleanup/</link><pubDate>Fri, 23 May 2008 00:47:37 +0100</pubDate><guid>https://blog.affien.com/archives/2008/05/23/dont-forget-etcinitdhibernate-cleanup/</guid><description>&lt;p&gt;Or it’ll bite you when you switch kernels often and forgot you hibernated on one.&lt;/p&gt;</description></item><item><title>Benchmarking CouchDB (2)</title><link>https://blog.affien.com/archives/2008/04/15/benchmarking-couchdb-2/</link><pubDate>Tue, 15 Apr 2008 13:59:42 +0100</pubDate><guid>https://blog.affien.com/archives/2008/04/15/benchmarking-couchdb-2/</guid><description>&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-v-per-b.png"&gt;&lt;img alt="" class="aligncenter size-full wp-image-311" decoding="async" height="250" loading="lazy" sizes="auto, (max-width: 400px) 100vw, 400px" src="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-v-per-b.png" srcset="https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-v-per-b.png 400w, https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-v-per-b-300x187.png 300w" title="couchdb-create-v-per-b" width="400"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a plot of the amount of documents created in a bulk update at the same time against the average amount of documents created per second it yields.&lt;/p&gt;</description></item><item><title>On the App Engine lock-in</title><link>https://blog.affien.com/archives/2008/04/15/on-the-app-engine-lock-in/</link><pubDate>Tue, 15 Apr 2008 13:31:13 +0100</pubDate><guid>https://blog.affien.com/archives/2008/04/15/on-the-app-engine-lock-in/</guid><description>&lt;p&gt;Some people are afraid that &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt; won’t be a really big success because it’s a lock-in. Give it a month and no doubt there will be a project which allows you to run AppEngine applications on your own servers, which (in my opinion) is even more interesting than AppEngine itself.&lt;/p&gt;</description></item><item><title>Benchmarking CouchDB (1)</title><link>https://blog.affien.com/archives/2008/04/02/benchmarking-couchdb-1/</link><pubDate>Wed, 02 Apr 2008 13:48:31 +0100</pubDate><guid>https://blog.affien.com/archives/2008/04/02/benchmarking-couchdb-1/</guid><description>&lt;p&gt;I’ve written a small benchmark for couchdb to test it’s document creation performance. A script creates &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; documents in total using bulk update to create &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; at the same time with &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;T&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; concurrent threads. The following graph show the time it takes to create an amount of documents against that amount of document for different values of &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; with &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;T=1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-t1.png"&gt;&lt;img alt="" class="aligncenter size-full wp-image-306" decoding="async" height="278" loading="lazy" sizes="auto, (max-width: 428px) 100vw, 428px" src="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-t1.png" srcset="https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-t1.png 428w, https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-t1-300x194.png 300w" title="couchdb-create-t1" width="428"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And for &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;T=2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; (two concurrent threads. Tested on a dual core machine)&lt;br&gt;
&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-t2.png"&gt;&lt;img alt="" class="aligncenter size-full wp-image-307" decoding="async" height="278" loading="lazy" sizes="auto, (max-width: 428px) 100vw, 428px" src="http://blog.w-nz.com/wp-content/uploads/2008/04/couchdb-create-t2.png" srcset="https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-t2.png 428w, https://blog.affien.com/wp-content/uploads/2008/04/couchdb-create-t2-300x194.png 300w" title="couchdb-create-t2" width="428"/&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;The values of B are 1, 2, 4, 5, 8, 11, 16, 22, 32, 45, 64, 90, 128, 181, 256, 362, 512, 724 and 1024&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;As you can see, a higher value of &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; causes the graph to shift to the right which means more &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; for the same time. Bulk update really does make a difference. &lt;em&gt;Or&lt;/em&gt; non-bulk-update really sucks. Also adding threads does help a bit, but not as much as expected.&lt;/p&gt;
&lt;p&gt;There are some more interesting graphs to plot (&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;B&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; against &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mover accent="true"&gt;&lt;mfrac&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;Δ&lt;/mi&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo stretchy="true"&gt;‾&lt;/mo&gt;&lt;/mover&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\overline {N \over \Delta T}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;). More graphs tomorrow.&lt;/p&gt;
&lt;p&gt;(For those interested, the &lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/04/results"&gt;raw data&lt;/a&gt; from which these graphs were plotted.)&lt;/p&gt;</description></item><item><title>CouchDB document creation performance</title><link>https://blog.affien.com/archives/2008/03/30/couchdb-document-creation-performance/</link><pubDate>Sun, 30 Mar 2008 00:24:10 +0100</pubDate><guid>https://blog.affien.com/archives/2008/03/30/couchdb-document-creation-performance/</guid><description>&lt;p&gt;&lt;a href="http://couchdb.org"&gt;CouchDB&lt;/a&gt; is a non-relational database which uses &lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;MapReduce&lt;/a&gt; inspired views to query data. There are lots of cool things to tell about its design, but I rather want to talk about its performance.&lt;/p&gt;
&lt;p&gt;Today I’ve been busy hacking together a little script to import all e-mails of a long e-mail thread into a couchdb database to write views to extract all kinds of statistics. I already imported these e-mails into a MySQL database a few months ago, but was quite disappointed by the (performance) limitations of SQL. The e-mail thread contains over 20,000 messages which weren’t a real problem for MySQL. When importing, however, couchdb was adding them at a rate of only a few dozen per second with a lot of (seek)noise of my HDD.&lt;/p&gt;
&lt;p&gt;So I decided to do a simple benchmark. First of, a simple script (&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/03/ser.py"&gt;ser.py&lt;/a&gt;) that adds empty documents sequentially. It’s averaging 16 per second. It occurred to me that couchdb waits for a &lt;code&gt;fsync&lt;/code&gt; before sending a response and that asynchronously the performance would be way better. A simple modification to the script later (&lt;a href="http://blog.w-nz.com/wp-content/uploads/2008/03/par.py"&gt;par.py&lt;/a&gt;) it still averaged 16 creations per second.&lt;/p&gt;
&lt;p&gt;I guess, for I haven’t yet figured out how to let &lt;code&gt;strace&lt;/code&gt;s tell me, that it’s the &lt;code&gt;fsync&lt;/code&gt; after each object creation which causes the mess. couchdb itself doesn’t write or seek a lot, but my &lt;em&gt;journaling&lt;/em&gt; filesystem (XFS) does on a &lt;code&gt;fsync&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Can anyone test it on a different filesystem?&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; Around 17/sec with &lt;code&gt;reiserfs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; I had some trouble with the bulk update feature. I switched from svn to the 0.7.2 release. I got about 600/sec, which dropped to a steady-ish 350/sec when using sequential bulkupdates of 100 docs. Two bulk updates in parallel yield about 950/sec initially, dropping to 550/sec after a while. Three parallel updates yield similar performance.&lt;/p&gt;</description></item><item><title>Interrupting a select without a timeout</title><link>https://blog.affien.com/archives/2008/03/11/interrupting-a-select-without-a-timeout/</link><pubDate>Tue, 11 Mar 2008 23:24:30 +0100</pubDate><guid>https://blog.affien.com/archives/2008/03/11/interrupting-a-select-without-a-timeout/</guid><description>&lt;p&gt;&lt;code&gt;select&lt;/code&gt; is a POSIX syscall which allows you to wait on several different filedescriptors (including sockets) for the event that they won’t block on write; won’t block or read or are in error. This syscall is very convenient when you’re writing a server.&lt;/p&gt;
&lt;p&gt;When I want to shutdown an instance of the server, I have to interrupt the &lt;code&gt;select&lt;/code&gt;. I have yet to find a satisfying way of doing this. At the moment I create a pair of linked sockets with &lt;code&gt;socketpair&lt;/code&gt;. I include one of them to the sockets on which to block until there is data to read in the &lt;code&gt;select&lt;/code&gt; call. To interrupt, I simply write some data to the other socket which will cause data to be available on the socket which in turn will interrupt the &lt;code&gt;select&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There must be a more elegant solution.&lt;/p&gt;</description></item><item><title>wlan0_rename</title><link>https://blog.affien.com/archives/2008/03/08/wlan0_rename/</link><pubDate>Sat, 08 Mar 2008 14:07:49 +0100</pubDate><guid>https://blog.affien.com/archives/2008/03/08/wlan0_rename/</guid><description>&lt;p&gt;If udev has problems assigning &lt;code&gt;wlan0&lt;/code&gt; to &lt;code&gt;wlan0&lt;/code&gt; (as given by the kernel) and instead lets you end up with an ugly &lt;code&gt;wlan0_rename&lt;/code&gt; or alike, you might want to check whether you’ve got stray udev config files in &lt;code&gt;/etc/udev/rules.d/&lt;/code&gt; like &lt;code&gt;70-persistent-net.rules&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>X61s (2)</title><link>https://blog.affien.com/archives/2008/03/07/x61s-2/</link><pubDate>Fri, 07 Mar 2008 15:37:07 +0100</pubDate><guid>https://blog.affien.com/archives/2008/03/07/x61s-2/</guid><description>&lt;p&gt;And here are some pictures of my X61s.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/~bas/x61s/dsc_0001.jpg"&gt;&lt;img src="http://w-nz.com/~bas/x61s/dsc_0001.thumb.jpg" alt=""&gt;&lt;/a&gt;&lt;a href="http://w-nz.com/~bas/x61s/dsc_0002.jpg"&gt;&lt;img src="http://w-nz.com/~bas/x61s/dsc_0002.thumb.jpg" alt=""&gt;&lt;/a&gt;&lt;a href="http://w-nz.com/~bas/x61s/dsc_0003.jpg"&gt;&lt;img src="http://w-nz.com/~bas/x61s/dsc_0003.thumb.jpg" alt=""&gt;&lt;/a&gt;&lt;a href="http://w-nz.com/~bas/x61s/dsc_0004.jpg"&gt;&lt;img src="http://w-nz.com/~bas/x61s/dsc_0004.thumb.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>X61s (1)</title><link>https://blog.affien.com/archives/2008/03/06/x61s-1/</link><pubDate>Thu, 06 Mar 2008 23:35:47 +0100</pubDate><guid>https://blog.affien.com/archives/2008/03/06/x61s-1/</guid><description>&lt;p&gt;I’ve been the lucky owner of a Thinkpad X61s for a bit more than a week now. It’s a light and small 12.1 inch notebook. It’s structurally very solid and has got almost the same full size keyboard as my 14.1inch T60. (The enter, tab, shift and alike keys are shortened in width).&lt;/p&gt;
&lt;p&gt;The installation of &lt;a href="http://gentoo.org"&gt;Gentoo&lt;/a&gt; went quite smooth. For those interested the &lt;a href="http://w-nz.com/~bas/x61s/xorg.conf"&gt;xorg.conf&lt;/a&gt;, &lt;a href="http://w-nz.com/~bas/x61s/make.conf"&gt;make.conf&lt;/a&gt; and kernel &lt;a href="http://w-nz.com/~bas/x61s/config"&gt;.config&lt;/a&gt; I use.&lt;/p&gt;
&lt;p&gt;Internal mic/speaker and external jacks; video; DRI and AIGLX; USB; PCMCIA; wireless; fingerprint reader and ethernet all seem to work just fine. I haven’t tested the firewire, ssd slot, bluetooth and n-capabilities of the wireless yet.&lt;/p&gt;
&lt;p&gt;In comparison with my T60 the volume and the backlight buttons aren’t hardware controlled. Gnome recognizes the volume buttons, but not the backlight ones. I’m still working on those.&lt;/p&gt;</description></item><item><title>ssmtp segfault in sendmail on Gentoo</title><link>https://blog.affien.com/archives/2008/02/26/ssmtp-segfault-in-sendmail-on-gentoo/</link><pubDate>Tue, 26 Feb 2008 21:39:52 +0100</pubDate><guid>https://blog.affien.com/archives/2008/02/26/ssmtp-segfault-in-sendmail-on-gentoo/</guid><description>&lt;p&gt;Disabling the &lt;code&gt;md5sum&lt;/code&gt; useflag might fix it.&lt;/p&gt;
&lt;p&gt;Thanks to Bram for the tip.&lt;/p&gt;</description></item><item><title>Fosdem (2)</title><link>https://blog.affien.com/archives/2008/02/25/fosdem-2/</link><pubDate>Mon, 25 Feb 2008 00:25:35 +0100</pubDate><guid>https://blog.affien.com/archives/2008/02/25/fosdem-2/</guid><description>&lt;p&gt;I have just returned from &lt;a href="http://www.fosdem.org/2008/"&gt;Fosdem 2008&lt;/a&gt;. The trip by car to Bruxelles was by Dutch standards quite long, 3 hours. Volker, who did the hotel bookings for the FSFE, was kind enough to also book a room for me and my brother. For the &lt;a href="http://www.astridhotel.be/"&gt;3-star hotel&lt;/a&gt;, which normally would cost you 200,– per night, we only had to pay about 70,– p/n. I did expect group discount, but that it would be so enormous was a surpise. I’m not complaining though :).&lt;/p&gt;
&lt;p&gt;After the check-in we went for a quick diner and straight of to the &lt;a href="http://www.deliriumcafe.be/"&gt;Delirium Café&lt;/a&gt; for the “Beer Event”. The café, even though it’s the largest one I’ve ever visited, was barely big enough for the masses of geeks. One could buy a ‘red dot’ from one of the organizers for 20,– euros. With it you can order any beer (one of the 25 on the tap) at the bar without paying until you spend the 20,– euros. This wasn’t checked though. I feel it hard to imagine, and my head felt even harder the next morning, that one would consume more. On that next morning the real magnitude of the conference became apparent. The first talk, at a large (really, large) college room at the Free University of Bruxelles, was attended by at least a thousand if it weren’t two-thousand people.&lt;/p&gt;
&lt;p&gt;The talk about Perl 6 was the most interesting for me. I didn’t really like Perl &amp;lt;5 primarily because of having too many ways to do the same in exactly the same way but with a different syntax. I knew that Perl 6 was a total and backwards incompatible redesign of the language, build on top of a generic and good virtual machine called &lt;a href="http://www.parrotcode.org/"&gt;Parrot&lt;/a&gt;. Parrot, which I hadn’t given a proper look yet, turned out to be a lot greater than expected. You write support for a new language in Parrot by writing in a subset of Perl 6, which with it’s new Regular Expressions and specializations (tokens: regex without backtracking, etc), was looking very suited for it.&lt;br&gt;
Except for all the new syntactic very very sweet sugar (on which I won’t (yet) elaborate) they added in Perl 6, the greatest one (which is actually more of a Parrot thing) is being able to extend Perl during runtime: writing new parser rules. One application is being able to define ‘!’ as a faculty operator. I’m itching to play with it.&lt;/p&gt;
&lt;p&gt;Another very interesting talk was the one about &lt;a href="http://www.tungstengraphics.com/wiki/index.php/Gallium3D"&gt;Gallium3D&lt;/a&gt;, which is an effort to rework the 3D API on Linux and Xorg for 3D accelerator drivers. It primarily abstracts most of the operations of the video card to being a very specialized language processor and not entirely surprising makes heavy use of the &lt;a href="http://llvm.org/"&gt;llvm&lt;/a&gt;. The abstraction was effective enough to being able to take a driver originally written for Linux, rework it for Gallium3D and actually being able to be run on a Windows version of Gallium. That it runs on Windows really can’t bother that much people. That it also now runs on Cell’s SMP’s, can. The speaker joked that one finally can play 3D games on your PS3 [ on Linux ].&lt;/p&gt;
&lt;p&gt;Most of the talks I attended were pretty interesting. Most of the speakers, though, weren’t that great speakers. The thing I missed most with FOSDEM was that there was no easy way to get in touch with people of a certain project. There were booths of a lot of projects, but there the people behind the booth were just standing there to show you stuff in the hallway that was too narrow. There were separate rooms for projects where there were talks given about the project, but there was no real time in between. A few hours nothing but people of the project meeting in a project room would have been great.&lt;/p&gt;
&lt;p&gt;Miscellaneously, the OLPC is a great toy; the EEE is even uglier than it looks on the web; the MacBook Air is even thinner than you think and the FSFE people with whom we stayed at the hotel were great. I could tell a lot more, but quite frankly I’m very tired and sleep calls.&lt;/p&gt;</description></item><item><title>Fosdem (1)</title><link>https://blog.affien.com/archives/2008/02/22/fosdem-1/</link><pubDate>Fri, 22 Feb 2008 01:44:21 +0100</pubDate><guid>https://blog.affien.com/archives/2008/02/22/fosdem-1/</guid><description>&lt;p&gt;Tomorrow I’ll travel the short distance to Bruxelles to visit &lt;a href="http://www.fosdem.org/"&gt;Fosdem&lt;/a&gt;. I’m pretty excited :).&lt;/p&gt;</description></item><item><title>Codeyard 2008</title><link>https://blog.affien.com/archives/2008/02/12/codeyard-2008/</link><pubDate>Tue, 12 Feb 2008 20:54:43 +0100</pubDate><guid>https://blog.affien.com/archives/2008/02/12/codeyard-2008/</guid><description>&lt;p&gt;&lt;a href="http://codeyard.net/"&gt;Codeyard&lt;/a&gt; is a project of the &lt;a href="http://ru.nl"&gt;RU&lt;/a&gt; to stimulate high school students for Free and Opensource Software in the Netherlands. Primarily they offer hosting and guidance for setting up projects. They also organize (great!) monthly meetings at the university where participants meet.&lt;/p&gt;
&lt;p&gt;To motivate people to join, they organize a yearly award sponsored by &lt;a href="http://www.capgemini.com/"&gt;Capgemini&lt;/a&gt; for the best project. With a friend, Noud, and my brother Bram we participated in their first year (2006) and &lt;a href="http://blog.w-nz.com/archives/2006/07/01/sinp-codeyard/"&gt;won the award&lt;/a&gt;. This year, I have the honor to join as a member of the jury.&lt;/p&gt;
&lt;p&gt;If you’re interested, you can visit one of the “community days”. The &lt;a href="http://www.codeyard.net/scholier/commuday.php"&gt;next one&lt;/a&gt; is this Saterday. There will also be a presentation by the people who cracked the “OV-kaart”, which should be quite interesting.&lt;/p&gt;</description></item><item><title>Evolving the Object Paradigm</title><link>https://blog.affien.com/archives/2008/01/31/evolving-the-object-paradigm/</link><pubDate>Thu, 31 Jan 2008 13:39:02 +0100</pubDate><guid>https://blog.affien.com/archives/2008/01/31/evolving-the-object-paradigm/</guid><description>&lt;p&gt;Kaja is writing &lt;a href="http://kajafumei.blogspot.com/2008/01/evolving-object-oriented-paradigm-part.html"&gt;a series of articles&lt;/a&gt; on the shortcomings and solutions to the current object paradigm. Very interesting.&lt;/p&gt;</description></item><item><title>Bye bye Reiser4</title><link>https://blog.affien.com/archives/2008/01/23/bye-bye-reiser4/</link><pubDate>Wed, 23 Jan 2008 15:44:10 +0100</pubDate><guid>https://blog.affien.com/archives/2008/01/23/bye-bye-reiser4/</guid><description>&lt;p&gt;A few days ago my root partition (formatted Reiser4) corrupted on my notebook. [ the usual IO hangups and nasty output in dmesg ]. Probably due to the usual wear and tear a notebook has to suffer or a faulty suspend cycle causing bogus IO. Something I suffered a few times before and didn’t think it would be a great deal. This time, though, &lt;code&gt;fsck.reiser4&lt;/code&gt; said it was all ok. That meant I was pretty screwed, for I knew it didn’t work correctly.&lt;/p&gt;
&lt;p&gt;I lended a USB hdd, booted up to a fallback installation on a separate ext2 partition and tried to copy over everything to the USB hdd. It was quite tricky to copy over as much as I could and remembering the point where it started to crash when reading it. Luckily, I salvaged my whole &lt;code&gt;/home&lt;/code&gt;. &lt;code&gt;/var&lt;/code&gt;, &lt;code&gt;/bin&lt;/code&gt;, &lt;code&gt;/usr/share&lt;/code&gt; and a lot of other trees weren’t that lucky.&lt;/p&gt;
&lt;p&gt;Formatted to XFS, copied everything I got back to the HDD and copied a Gentoo stage 3 tarball over it. A stage 3 tarball contains a minimal installation to which can be chrooted and then booted and from which the rest of the system can be build: the usual method to install Gentoo. I didn’t lost my &lt;code&gt;world&lt;/code&gt; nor &lt;code&gt;/etc/make.conf&lt;/code&gt; file. A small script later I got portage re-emerging every package I had installed on the system. Still 200 to go at the moment, but at least I’m now in a partially functioning gnome desktop, which is a lot more usable than TWM (ugly default WM of Xorg).&lt;/p&gt;
&lt;p&gt;XFS performs quite well. It’s latency under load is a &lt;em&gt;lot&lt;/em&gt; smaller than Reiser4’s. (It’s a pity I haven’t yet come to try the new patches in mm to help Reiser4 a bit with that problem. And also becasuse Reiser4 seems so close to inclusion, reading Andrew’s merge plans). In contrast, XFS sucks at handling a lot of small files compared to Reiser4. This is all just a feeling though. I haven’t tested anything. The most important characteristic of a FS, though, is only apparent after long use: the influence of fragmentation. Having looked around a bit, &lt;a href="http://oss.oracle.com/projects/btrfs/"&gt;btrfs&lt;/a&gt; seems interesting.&lt;/p&gt;
&lt;p&gt;On a sidenote on latency: my mom runs Ubuntu with EXT3 and even though EXT3 sucks in practically every single performance benchmark it has seem to got a superb responsiveness. Ah, 150 packages to go.&lt;/p&gt;</description></item><item><title>Linux 2.6.24-bw-r34</title><link>https://blog.affien.com/archives/2008/01/20/linux-2624-bw-r3/</link><pubDate>Sun, 20 Jan 2008 01:24:50 +0100</pubDate><guid>https://blog.affien.com/archives/2008/01/20/linux-2624-bw-r3/</guid><description>&lt;p&gt;Again an update for my bw-tree. There isn’t a tree that includes &lt;a href="http://en.wikipedia.org/wiki/Reiser4"&gt;reiser4&lt;/a&gt; and &lt;a href="http://tuxonice.net/"&gt;TuxOnIce&lt;/a&gt; without a lot of other bloat, so I created one myself.&lt;/p&gt;
&lt;p&gt;Download the &lt;a href="http://w-nz.com/~bas/projects/bw-r4-for-2.6.24.diff.bz2"&gt;big diff&lt;/a&gt; or the seperate patches &lt;a href="http://w-nz.com/~bas/projects/bw-r4-for-2.6.24.tar.bz2"&gt;broken out&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Note&lt;/ins&gt; I pulled in new patches for reiser4 from the -mm tree against -rc8 which &lt;em&gt;should&lt;/em&gt; fix the Reiser4 flush problem a bit.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; Patched against 2.6.24 stable. New TuxOnIce patched added and the genpatches. Please note that I haven’t tested Reiser4 &lt;a href="http://blog.w-nz.com/archives/2008/01/23/bye-bye-reiser4/"&gt;thoroughly enough&lt;/a&gt; on this version.&lt;/p&gt;</description></item><item><title>2008</title><link>https://blog.affien.com/archives/2008/01/01/2008/</link><pubDate>Tue, 01 Jan 2008 00:00:46 +0100</pubDate><guid>https://blog.affien.com/archives/2008/01/01/2008/</guid><description>&lt;p&gt;Happy newyear!&lt;/p&gt;</description></item><item><title>Tickle</title><link>https://blog.affien.com/archives/2007/12/28/tickle/</link><pubDate>Fri, 28 Dec 2007 18:34:15 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/28/tickle/</guid><description>&lt;p&gt;Tickle is a small Python serializer like &lt;a href="http://docs.python.org/lib/module-pickle.html"&gt;Pickle&lt;/a&gt;. It however aims at generating smaller output:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; len(tickle('hello'))&lt;br/&gt;
7&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; s = StringIO.StringIO()&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; pickle.dump('hello', s)&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; len(s.getvalue())&lt;br/&gt;
13&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Though the difference is and remains quite small, this alone is useful for serialization of small things in the case of for instance RPC. However, usually you already know what kind of data to expect and you don’t really bother about the type information. This can be done by specifying a template:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; obj = []&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; for i in xrange(100):&lt;br/&gt;
       obj.append((i, str(i)))&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; len(tickle(obj))&lt;br/&gt;
629&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; len(tickle(obj, template=(tuple, \&lt;br/&gt;
   ((tuple,((int,), (str,))),)*100)))&lt;br/&gt;
390&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Instead the *100 an iterator could be constructed, but that would clutter the example even more than it already is.) In comparison:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; s = StringIO.StringIO(); pickle.dump(obj, s)&lt;br/&gt;
&amp;gt;&amp;gt;&amp;gt; len(s.getvalue())&lt;br/&gt;
1680&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One big disadvantage of Tickle is speed. Pickle has got a nice C implementation, which is quite fast. &lt;a href="http://psyco.sourceforge.net/"&gt;Psyco&lt;/a&gt; helps a bit but not really enough for really big things. Even more so pickle is a bit smarter: it builds a LUT for instances to avoid duplicate data. However, in the situations where Tickle will be used (by me at least) that isn’t too big of an issue.&lt;/p&gt;
&lt;p&gt;You can download &lt;a href="http://w-nz.com/gitweb/gitweb.cgi?p=marietje.git;a=blob_plain;f=tickle/tickle.py;hb=master"&gt;tickle.py&lt;/a&gt; via &lt;a href="http://w-nz.com/gitweb/gitweb.cgi"&gt;gitweb&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Merry Christmas</title><link>https://blog.affien.com/archives/2007/12/24/merry-christmas-2/</link><pubDate>Mon, 24 Dec 2007 22:59:00 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/24/merry-christmas-2/</guid><description>&lt;p&gt;For happy a christmas!&lt;/p&gt;</description></item><item><title>linux 2.6.24-bw-r12</title><link>https://blog.affien.com/archives/2007/12/20/linux-2624-bw/</link><pubDate>Thu, 20 Dec 2007 23:07:05 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/20/linux-2624-bw/</guid><description>&lt;p&gt;There isn’t a (stable-ish) tree that includes reiser4 and TuxOnIce (suspend2), so I made one myself, based on 2.6.24&lt;del&gt;-rc5&lt;/del&gt;&lt;ins&gt;-rc&lt;del&gt;6&lt;/del&gt;7&lt;/ins&gt;.&lt;/p&gt;
&lt;p&gt;You can grab it as one big patch, &lt;a href="http://w-nz.com/~darkshines/projects/bw-r2-for-2.6.24-rc7.diff.bz2"&gt;bw&lt;ins&gt;-r&lt;del&gt;1&lt;/del&gt;2&lt;/ins&gt;-for-2.6.24&lt;del&gt;-rc5&lt;/del&gt;&lt;ins&gt;-rc&lt;del&gt;6&lt;/del&gt;7&lt;/ins&gt;.diff.bz2&lt;/a&gt;, or broken out: &lt;a href="http://w-nz.com/~darkshines/projects/bw-r2-for-2.6.24-rc7.tar.bz2"&gt;bw&lt;ins&gt;-r&lt;del&gt;1&lt;/del&gt;2&lt;/ins&gt;-for-2.6.24&lt;del&gt;-rc5&lt;/del&gt;&lt;ins&gt;-rc&lt;del&gt;6&lt;/del&gt;7&lt;/ins&gt;.tar.bz2&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Java crashing on xcb_xlib_unlock.</title><link>https://blog.affien.com/archives/2007/12/17/java-crashing-on-xcb_xlib_unlock/</link><pubDate>Mon, 17 Dec 2007 23:34:31 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/17/java-crashing-on-xcb_xlib_unlock/</guid><description>&lt;p&gt;When Java applications crash on linux with &lt;code&gt;xcb_xlib_unlock: Assertion `c-&amp;gt;xlib.lock' failed&lt;/code&gt; you should upgrade to &lt;code&gt;libxcb-1.1&lt;/code&gt; and add &lt;code&gt;LIBXCB_ALLOW_SLOPPY_LOCK=1&lt;/code&gt; to the environment.&lt;/p&gt;</description></item><item><title>rebuild-scm-ebuilds</title><link>https://blog.affien.com/archives/2007/12/08/rebuild-scm-ebuilds/</link><pubDate>Sat, 08 Dec 2007 19:51:37 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/08/rebuild-scm-ebuilds/</guid><description>&lt;p&gt;&lt;a href="http://w-nz.com/~darkshines/projects/rebuild-scm-ebuilds.tar.bz2"&gt;Two very simple ruby scripts (I love ruby!) and a little bash script&lt;/a&gt; that searches all ebuilds with 9999 in the name, orders them by dependencies and then emerge -a them. Very useful when you got a lot of 9999 ebuilds.&lt;/p&gt;</description></item><item><title>CaCert.org</title><link>https://blog.affien.com/archives/2007/12/08/cacertorg/</link><pubDate>Sat, 08 Dec 2007 13:20:46 +0100</pubDate><guid>https://blog.affien.com/archives/2007/12/08/cacertorg/</guid><description>&lt;p&gt;CaCert is a Certification Authority that works with a web of trust: people meet and assure (similar to keysigning) eachother. If you’ve been assured by enough people you’ll be able to let your ssl server key be certified by cacert. It’s a lot more secure than other CA’s who just give anyone a certificate who pays enough.&lt;/p&gt;
&lt;p&gt;Still a hierarchical system with a CA is flawed. When the CA is compromised, the whole system fails. PGP’s web of trust hasn’t got this weakness.&lt;/p&gt;
&lt;p&gt;(Got a nice shiny cacert certified ssl certificate on my webserver now)&lt;/p&gt;</description></item><item><title>Virtual packages in python</title><link>https://blog.affien.com/archives/2007/11/10/virtual-packages-in-python/</link><pubDate>Sat, 10 Nov 2007 22:11:07 +0100</pubDate><guid>https://blog.affien.com/archives/2007/11/10/virtual-packages-in-python/</guid><description>&lt;p&gt;When writing an application in python, it can be very convenient to be able to import a module from the top of your module tree. Eg. &lt;code&gt;import myapp.config&lt;/code&gt; instead of (python 2.5 only) relative imports: &lt;code&gt;import ....config&lt;/code&gt;. To do this one would have to make &lt;code&gt;myapp&lt;/code&gt; a package. The normal way to do this is to put your application directory (which now has to be named &lt;code&gt;myapp&lt;/code&gt;) somewhere in python’s package search path. This isn’t all to convenient.&lt;/p&gt;
&lt;p&gt;The solution: manually set up your package module:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import os&lt;br/&gt;
import sys&lt;br/&gt;
import imp&lt;br/&gt;
def setup_virtual_package(name, path=os.curdir):&lt;br/&gt;
    &amp;quot;&amp;quot;&amp;quot; Sets up a package at the given path with a given&lt;br/&gt;
     name &amp;quot;&amp;quot;&amp;quot;&lt;br/&gt;
    modulePath = os.path.abspath(path)&lt;br/&gt;
    f, fn, suffix = imp.find_module('__init__', &lt;br/&gt;
         [modulePath])&lt;br/&gt;
    imp.load_module(name, f, fn, suffix)&lt;br/&gt;
    sys.modules[name].__path__ = [modulePath]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now &lt;code&gt;import myapp.something&lt;/code&gt; works like a charm.&lt;/p&gt;</description></item><item><title>Xkcd</title><link>https://blog.affien.com/archives/2007/11/03/xkcd/</link><pubDate>Sat, 03 Nov 2007 13:56:33 +0100</pubDate><guid>https://blog.affien.com/archives/2007/11/03/xkcd/</guid><description>&lt;p&gt;Maybe I’m a bit late, but &lt;a href="http://xkcd.com/"&gt;xkcd&lt;/a&gt; is great.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://imgs.xkcd.com/comics/centrifugal_force.png" alt=""&gt;&lt;/p&gt;</description></item><item><title>Rome</title><link>https://blog.affien.com/archives/2007/10/22/rome/</link><pubDate>Mon, 22 Oct 2007 07:39:14 +0100</pubDate><guid>https://blog.affien.com/archives/2007/10/22/rome/</guid><description>&lt;p&gt;I’m visiting the city of Rome next week.&lt;/p&gt;</description></item><item><title>Ulrich Drepper on Memory</title><link>https://blog.affien.com/archives/2007/10/13/ulrich-drepper-on-memory/</link><pubDate>Sat, 13 Oct 2007 19:54:59 +0100</pubDate><guid>https://blog.affien.com/archives/2007/10/13/ulrich-drepper-on-memory/</guid><description>&lt;p&gt;Kernel hacker Ulrich Drepper has written a lengthy paper on the design and especially performance characteristics of memory of modern consumer hardware and it’s written for programmers. A great read so far (it’s published in parts by LWN):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lwn.net/Articles/250967/"&gt;What every programmer should know about memory&lt;/a&gt; by Ulrich Drepper.&lt;/p&gt;</description></item><item><title>Stupid PHP (1) (Strings are faster than Arrays)</title><link>https://blog.affien.com/archives/2007/09/23/stupid-php-1-strings-are-faster-than-arrays/</link><pubDate>Sun, 23 Sep 2007 18:05:14 +0100</pubDate><guid>https://blog.affien.com/archives/2007/09/23/stupid-php-1-strings-are-faster-than-arrays/</guid><description>&lt;p&gt;When I slowly build a big string out of little bits, the worst thing to do in most languages is to just use string concatenation:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;for(something) {&lt;br/&gt;
 str .= little_bit;&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Why? Everytime a little bit is added to &lt;code&gt;str&lt;/code&gt;, there must be a new string allocated big enough to contain &lt;code&gt;str&lt;/code&gt; and the new little bit. Then the actual &lt;code&gt;str&lt;/code&gt; must be copied in. In most languages there are constructs to efficiently build strings like this instead of concatenating. StringBuffer in C#. StringIO in Python.&lt;/p&gt;
&lt;p&gt;But no, PHP has to be stupid. There is no nice construct and you’ll end up using concatenation. So, I thought to be smart and make use of PHP array’s and &lt;code&gt;implode&lt;/code&gt;. Arrays are here for having elements added and removed all the time so they are properly buffered and should be great at having lots of small elements added. And when I want to pack it all into one big string, I can use PHP’s builtin &lt;code&gt;implode&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;I wanted to try it out and created two scripts: &lt;code&gt;a.php&lt;/code&gt; concats a little (10byte) string one million times and &lt;code&gt;b.php&lt;/code&gt; appends it to an array and then &lt;code&gt;implode&lt;/code&gt;s it. And because I’m also interested in the performance of &lt;code&gt;implode&lt;/code&gt; I got a script &lt;code&gt;c.php&lt;/code&gt; that’s identical to &lt;code&gt;b.php&lt;/code&gt; but doesn’t implode afterwards. These are the results:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;a.php (concat)&lt;/th&gt;
&lt;td&gt;0.320s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;b.php (array append and implode)&lt;/th&gt;
&lt;td&gt;0.814s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th&gt;c.php (array append)&lt;/th&gt;
&lt;td&gt;0.732s&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Indeed, string concatenation with all its allocation and copying is actually faster than plain simple array appending. PHP is stupid.&lt;/p&gt;</description></item><item><title>Stupid IE (2)</title><link>https://blog.affien.com/archives/2007/09/02/stupid-ie-2/</link><pubDate>Sun, 02 Sep 2007 14:02:46 +0100</pubDate><guid>https://blog.affien.com/archives/2007/09/02/stupid-ie-2/</guid><description>&lt;p&gt;To create a multiple select-box with javascript you need a &lt;em&gt;very&lt;/em&gt; ugly hack in IE.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if (navigator.appName.match(/Internet Explorer/)) {
	fsel = document.createElement(\&amp;#39;&amp;lt;SELECT MULTIPLE&amp;gt;\&amp;#39;);
} else {
	fsel = document.createElement(\&amp;#39;select\&amp;#39;);
	fsel.multiple = true;
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Stupid IE (1)</title><link>https://blog.affien.com/archives/2007/09/02/stupid-ie-1/</link><pubDate>Sun, 02 Sep 2007 13:51:19 +0100</pubDate><guid>https://blog.affien.com/archives/2007/09/02/stupid-ie-1/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;if(!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(el) {
		var i = 0;
		for(; i &amp;lt; this.length; i++)
			if(this[i] == el)
				return i;
		return -1;
	};
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>19</title><link>https://blog.affien.com/archives/2007/08/30/19/</link><pubDate>Thu, 30 Aug 2007 21:38:22 +0100</pubDate><guid>https://blog.affien.com/archives/2007/08/30/19/</guid><description>&lt;p&gt;Nuff said.&lt;/p&gt;</description></item><item><title>The (or at least a better) Solution to Spam</title><link>https://blog.affien.com/archives/2007/08/14/the-or-at-least-a-better-solution-to-spam/</link><pubDate>Tue, 14 Aug 2007 17:45:34 +0100</pubDate><guid>https://blog.affien.com/archives/2007/08/14/the-or-at-least-a-better-solution-to-spam/</guid><description>&lt;p&gt;There is no easy way to distinguish between a human and a spambot. It’s an arms race which we’ll always be behind. I’m talking here about spam in more general—not only on e-mail but also on for instance Wikipedia or on blogposts. Even if we would have a perfect-solution to test whether there is a human behind something, we still have to combat cheap labour in India: real people spamming “by hand”.&lt;/p&gt;
&lt;p&gt;I think the solution is a &lt;a href="http://en.wikipedia.org/wiki/Web_of_Trust"&gt;Web of Trust&lt;/a&gt; similar to that of PGP. An identity (not necessarily a person) publishes who she trusts (not to be spammy/phishy) or not trusts. Ideally everyone would be in one big web. Only someone who my blog via-via trusts may post.&lt;/p&gt;
&lt;p&gt;Obviously one still may gather trust of people over time and enter the web of trust and then start spamming with that identity. However, then that identity will be marked untrusted by people and also the people who initially marked the identity as trusted will be less trusted. Also, there are way more sophisticated measures of establishment in the web/trust to conceive than just being trusted via-via by one identity.&lt;/p&gt;
&lt;p&gt;There is no way to prevent spam perfectly, but the amount of work that has to go in to making an identity trusted and established in the web is several orders of magnitude greater than any other protection we have. The big problem: we don’t have such an ubiquitous web of trust yet. (Yes, it’ll be in &lt;a href="http://blog.w-nz.com/archives/2006/07/01/sinp/"&gt;SINP&lt;/a&gt; if I’ll get around to working on it)&lt;/p&gt;</description></item><item><title>Section 202c of the German computer crime laws</title><link>https://blog.affien.com/archives/2007/08/13/section-202c-of-the-german-computer-crime-laws/</link><pubDate>Mon, 13 Aug 2007 17:46:33 +0100</pubDate><guid>https://blog.affien.com/archives/2007/08/13/section-202c-of-the-german-computer-crime-laws/</guid><description>&lt;p&gt;This section has come into effect over the weekend. It makes it illegal to create, possess, obtain, provide access to, yield, distribute or otherwise allow access to lots of widespread tools that can be used to breach security. Take for instance nmap.&lt;/p&gt;
&lt;p&gt;This law does not only impede our freedom (of speech), research, decrease security and allow for misuse, but more importantly it won’t even stop the real criminals.&lt;/p&gt;
&lt;p&gt;Stefan of the Month of PHP Bugs Project writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The law does not affect our freedom of speech to report and inform about security vulnerabilities and how to exploit them.&lt;/p&gt;
&lt;p&gt;We are just not allowed to create/distribute/use software that could be used as “hacking tools”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where would they draw the line between reporting/informing about a vulnerability and how to exploit it and the actual source code to do it. Would pseudocode be illegal? Would literate code be illegal? Also there would be no way for security researchers to try out their work.&lt;/p&gt;
&lt;p&gt;What will happen in the worst case if similar laws are accepted in other countries and enforced, is that vendors will rather cover up all vulnerabilities using these laws instead of securing it. That there are lots of ready-to-use exploits is good. It’s a very good incentive for security.&lt;/p&gt;
&lt;p&gt;That there will always be a leak in a piece of software that someone will be able to find on his own will not be changed by this law. Also there will be no way to stop the real criminals from creating and distributing tools underground. Now everyone still knows what kind of tools are around and will know what to expect.&lt;/p&gt;</description></item><item><title>bas@fsfe.org</title><link>https://blog.affien.com/archives/2007/08/06/basfsfeorg/</link><pubDate>Mon, 06 Aug 2007 01:00:13 +0100</pubDate><guid>https://blog.affien.com/archives/2007/08/06/basfsfeorg/</guid><description>&lt;p&gt;I just got back from Wacken Open Air 2007 (it was great!) and noticed that my bas@fsfe.org account has been activated :).&lt;/p&gt;</description></item><item><title>Wacken</title><link>https://blog.affien.com/archives/2007/07/27/wacken/</link><pubDate>Fri, 27 Jul 2007 02:57:56 +0100</pubDate><guid>https://blog.affien.com/archives/2007/07/27/wacken/</guid><description>&lt;p&gt;I’ll be up early tomorrow, Saturday, to take the train with lots of friends to the little town of Wacken in Germany. (Actually, there is no train station in Wacken, so we need to hire a cab someway for the last dozen kilometers)&lt;/p&gt;
&lt;p&gt;Sunday morning the camping of the &lt;a href="http://www.wacken.com/"&gt;Wacken Open Air festival&lt;/a&gt; will open. The festival itself will start on Thursday. I hope to be home again the first Sunday of August.&lt;/p&gt;</description></item><item><title>linux 2.6.22-bw-r1</title><link>https://blog.affien.com/archives/2007/07/12/linux-2622-bw-r1/</link><pubDate>Thu, 12 Jul 2007 16:53:17 +0100</pubDate><guid>https://blog.affien.com/archives/2007/07/12/linux-2622-bw-r1/</guid><description>&lt;p&gt;There isn’t a tree that contains reiser4, suspend2 and the gentoo patches — so I created one. This revision adds the -stable patches and the new gentoo patches.&lt;/p&gt;
&lt;p&gt;One big patch: &lt;a href="http://w-nz.com/~darkshines/projects/bw-r1-for-2.6.22.diff.bz2"&gt;bw-r1-for-2.6.22.diff.bz2&lt;/a&gt;&lt;br&gt;
Patches broken out: &lt;a href="http://w-nz.com/~darkshines/projects/bw-r1-for-2.6.22.tar.bz2"&gt;bw-r1-for-2.6.22.tar.bz2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To apply the one big patch, use: &lt;code&gt;bzcat bw-r1-for-2.6.22.diff.bz2 | patch -p1&lt;/code&gt; inside a vanilla 2.6.22.&lt;/p&gt;</description></item><item><title>“Nothing to hide”</title><link>https://blog.affien.com/archives/2007/07/11/nothing-to-hide/</link><pubDate>Wed, 11 Jul 2007 02:19:23 +0100</pubDate><guid>https://blog.affien.com/archives/2007/07/11/nothing-to-hide/</guid><description>&lt;blockquote&gt;
&lt;p&gt;In this short essay, written for a symposium in the San Diego Law Review, Professor Daniel Solove examines the “nothing to hide” argument. When asked about government surveillance and data mining, many people respond by declaring: “I’ve got nothing to hide.” According to the “nothing to hide” argument, there is no threat to privacy unless the government uncovers unlawful activity, in which case a person has no legitimate justification to claim that it remain private. The “nothing to hide” argument and its variants are quite prevalent, and thus are worth addressing. In this essay, Solove critiques the “nothing to hide” argument and exposes its faulty underpinnings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://papers.ssrn.com/sol3/papers.cfm?abstract_id=998565"&gt;“I’ve Got Nothing to Hide” and Other Misunderstandings of Privacy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not only is its subject very relevant, the Essay is very well written and a pleasure to read.&lt;/p&gt;</description></item><item><title>Online Cycle Detection in Directed Graphs</title><link>https://blog.affien.com/archives/2007/07/02/online-cycle-detection-in-directed-graphs/</link><pubDate>Mon, 02 Jul 2007 22:01:45 +0100</pubDate><guid>https://blog.affien.com/archives/2007/07/02/online-cycle-detection-in-directed-graphs/</guid><description>&lt;p&gt;A short while ago I came across a quite interesting problem. Design a datastructure (and algorithms) to maintain a &lt;a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph"&gt;Directed Acyclic Graph&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There has to be only one operation: adding a link between two given nodes. This operation must be able to detect and deny any new link that would cause a cycle. For simplicity, nodes are identified by sequential ids starting with 0.&lt;/p&gt;
&lt;p&gt;An example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;addLink 0, 1 -&amp;gt; True&lt;br/&gt;
addLink 1, 2 -&amp;gt; True&lt;br/&gt;
addLink 2, 0 -&amp;gt; False # Fails because it would create a cycle&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;addLink 0, 1 -&amp;gt; True&lt;br/&gt;
addLink 1, 2 -&amp;gt; True&lt;br/&gt;
addLink 0, 2 -&amp;gt; True # This isn't a real cycle, so it's perfectly fine&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It’s rather trivial to create a &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant="script"&gt;O&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;ℓ&lt;/mi&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\mathcal{O}\left(n+\ell\right)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; (where &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; is the number of nodes and &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant="normal"&gt;ℓ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\ell&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; the number of links). I conjecture there exists a &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant="script"&gt;O&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mi&gt;log&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\mathcal{O}\left(\log n\right)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; algorithm.&lt;/p&gt;</description></item><item><title>Xgl with RandR 1.3 and Ati</title><link>https://blog.affien.com/archives/2007/06/25/xgl-with-randr-13-and-ati/</link><pubDate>Mon, 25 Jun 2007 10:18:26 +0100</pubDate><guid>https://blog.affien.com/archives/2007/06/25/xgl-with-randr-13-and-ati/</guid><description>&lt;p&gt;You have to add &lt;code&gt;Option &amp;quot;DesktopSetup&amp;quot; &amp;quot;single&amp;quot;&lt;/code&gt; to your ati’s &lt;code&gt;Device&lt;/code&gt; section in &lt;code&gt;xorg.conf&lt;/code&gt; otherwise Xgl will think you’ve got two screens if you’ve got two adapters even if you just use one (which is the case with my Thinkpad) and will miserably fail on the second unattached screen.&lt;/p&gt;</description></item><item><title>Graduated</title><link>https://blog.affien.com/archives/2007/06/15/graduated/</link><pubDate>Fri, 15 Jun 2007 00:20:48 +0100</pubDate><guid>https://blog.affien.com/archives/2007/06/15/graduated/</guid><description>&lt;p&gt;Today I received a long anticipated phone call from my mentor who took away the doubt and let me know that I graduated for my &lt;a href="http://en.wikipedia.org/wiki/Voorbereidend_Wetenschappelijk_Onderwijs"&gt;VWO exams&lt;/a&gt; at the Stedelijk Gymnasium Nijmegen, which is a matriculation exam.&lt;/p&gt;
&lt;p&gt;With mixed feeling I look back at seven long years. It certainly shouldn’t have took 7 years, nor 6, not even 3. But espacially in my last few years I came to appreciate the tons of very different people with whom I spend the days. A diversity I won’t find in that extend within the students of Maths and Physics which I intend to study next year at the Radboud University in Nijmegen.&lt;/p&gt;
&lt;p&gt;For one thing I certainly wouldn’t have want to have missed these last few years. Some say they’re the best of your life. I do really look forward to university, though.&lt;/p&gt;
&lt;p&gt;For those interested, I’ve planned an “Examenfeest” with some others in a nice club in Nijmegen. Send me an e-mail if you happen to be in the neighborhood and care to join.&lt;/p&gt;</description></item><item><title>Syslets and other untrusted kernelspace programming</title><link>https://blog.affien.com/archives/2007/06/11/syslets-and-other-untrusted-kernelspace-programming/</link><pubDate>Mon, 11 Jun 2007 01:39:04 +0100</pubDate><guid>https://blog.affien.com/archives/2007/06/11/syslets-and-other-untrusted-kernelspace-programming/</guid><description>&lt;p&gt;In the wake of creating true async. IO in the linux kernel Ingo worked on so called syslets. A syslet is nothing more than one async system call to chain together a few arbitrary system calls. An example syslet would be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1. Read from file descriptor 123&lt;br&gt;
2. If 1 returned with error, break&lt;br&gt;
3. Write which was read to file descriptor 321&lt;br&gt;
4. If 3 succeeded jump to 1 otherwise break&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is represented by a few struct’s linked together of which the first is passed on to the kernel with the syslet system call. The systemcall returns practically directly and eventually the application can be notified (or can wait) on the syslet to complete. This could safe an enormous amount of system calls. This means way less context switches, which is very good for performance.&lt;/p&gt;
&lt;p&gt;Syslets dawn, in a very primitive manner, kernelspace scripting. But hey, wasn’t kernelside scripting the thing that all linux dev’s dreaded? Wasn’t it Linus who joked that he would be in a mental institute whilst releasing Linux 3 with a VB message pump? Yes, they’re afraid of putting untrusted programs/scripts in kernelspace and they’ll barely acknowledge that syslets is the first step.&lt;/p&gt;
&lt;p&gt;The problem with the current full-featured scripting languages is that they are, well, full-features gone wrong: they’re bloated and not really secure. In kernelspace you can’t allow any memory except for the scripts’ own to be accessed, not to mention the restrictions on resources and virtual memory won’t help you there. Most scripting languages weren’t developed with these restrictions in mind. Most languages have got evil functions in dark corners of the standard library that will allow you to do really evil stuff with memory.&lt;/p&gt;
&lt;p&gt;As far as I know only .net (thus mono) have got a quite rigorous trust framework build in. .Net is bloated and proprietary and Mono is still (and probably will never be) feature complete though still being very bloated.&lt;/p&gt;
&lt;p&gt;A very simple safe language is what we need, of which a compiler daemon is running as a system service, with which untrusted userspace programs can have scripts running in the kernel. I’m tempted to use one of the brainf*ck JIT’s, they’re small enough to thoroughly review :).&lt;/p&gt;
&lt;p&gt;A kernelspace interpreter would do to, though, as a PoC.&lt;/p&gt;</description></item><item><title>Linux 2.6.21-bw-r1</title><link>https://blog.affien.com/archives/2007/06/10/linux-2621-bw-r1/</link><pubDate>Sun, 10 Jun 2007 23:51:48 +0100</pubDate><guid>https://blog.affien.com/archives/2007/06/10/linux-2621-bw-r1/</guid><description>&lt;p&gt;There isn’t a tree that contains reiser4, suspend2 and the gentoo patches — so I created one. This revision adds the -stable patches, new gentoo patches and some powertop patches.&lt;/p&gt;
&lt;p&gt;One big patch: &lt;a href="http://w-nz.com/~darkshines/projects/bw-r1-for-2.6.21.diff.bz2"&gt;bw-r1-for-2.6.21.diff.bz2&lt;/a&gt;&lt;br&gt;
Patches broken out: &lt;a href="http://w-nz.com/~darkshines/projects/bw-r1-for-2.6.21.tar.bz2"&gt;bw-r1-for-2.6.21.tar.bz2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To apply the one big patch, use: &lt;code&gt;bzcat bw-r1-for-2.6.21.diff.bz2 | patch -p1&lt;/code&gt; inside a vanilla 2.6.21.&lt;/p&gt;</description></item><item><title>Upgrading wordpress with git</title><link>https://blog.affien.com/archives/2007/06/07/upgrading-wordpress-with-git/</link><pubDate>Thu, 07 Jun 2007 22:03:56 +0100</pubDate><guid>https://blog.affien.com/archives/2007/06/07/upgrading-wordpress-with-git/</guid><description>&lt;p&gt;I didn’t like upgrading wodpress much. Everytime I did it, I needed to re-apply all my little tweaks to the new wordpress. It took too much time.&lt;/p&gt;
&lt;p&gt;I tried to &lt;code&gt;diff -uNr&lt;/code&gt; on the current version I was running and the newer version and then applying the resulting diff to the current version, but it seems wordpress has been backporting changes so I got conflicts, quite a lot of them.&lt;/p&gt;
&lt;p&gt;Because I was quite tired of porting my changes, I’ve tried git, the Source Code Managment tool used by the linux kernel, to do it for me:&lt;/p&gt;
&lt;p&gt;I did this all in the parent directory of the root of blog.w-nz.com. This folder contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;htdocs&lt;/code&gt; current installation (2.1.2)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2.1.2&lt;/code&gt; the unmodified wordpress&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2.2.0&lt;/code&gt; the new wordpress I want to upgrade to&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First, I created an empty git repository:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;mkdir git; cd git; git init-db; cd ..&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then I copied over the unmodified version of wordpress I was running, and commited them:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cp 2.1.2/* git -R&lt;br/&gt;
cd git&lt;br/&gt;
git add *&lt;br/&gt;
git commit -a -s&lt;br/&gt;
cd ..&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then I copied over my current installation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cp htdocs/* git -R&lt;br/&gt;
git status # lets see what changed&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are lots of files like uploads I want git to ignore, so I edit &lt;code&gt;.gitignore&lt;/code&gt; to make git ignore them. There weren’t any files I added though, otherwise I’d had to run &lt;code&gt;git add&lt;/code&gt; to let git know.&lt;/p&gt;
&lt;p&gt;And let commit my changes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git commit -a -s&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, lets go back to the original commit — the clean 2.1.2 wordpress — and start a branch from there:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git checkout HEAD^ # HEAD^ means parent commit of HEAD: the previous commit&lt;br/&gt;
git checkout -b tmp # create a new branch tmp from here&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now I’m in a branch without my own changes, which was forked from the master branch. Lets apply the new wordpress on this branch:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cd ..&lt;br/&gt;
cp 2.2.0/* git -R&lt;br/&gt;
cd git&lt;br/&gt;
git status # see what changed&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git-status&lt;/code&gt; showed me that there are a few new files in wordpress 2.2.0, I &lt;code&gt;git-add&lt;/code&gt;-ed all of these new files. And then committed it all:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git commit -a -s&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now I’ve got two branches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;master&lt;/code&gt; which contains wordpress 2.1.2 with my own changes on top as a commit&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tmp&lt;/code&gt; which is forked from the wordpress 2.1.2 from the master branch without my own changes but with the 2.2.0 changes on top&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I want to do is to reapply the 2.2.0 changes on top of my current changes’ commit instead of on top of the 2.1.2 commit. To do this, git has a very powerfull util called &lt;code&gt;git-rebase&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This will search down the tree until the point where the current branch (tmp) forked from the target branch (master). Then it will re-apply all commits in between on the latest commit of the target branch.&lt;/p&gt;
&lt;p&gt;Just like if I’d use diff/patch I get a merge conflict. &lt;code&gt;git rebase&lt;/code&gt; lets me know this and &lt;code&gt;git status&lt;/code&gt; shows me which one are these. The one little difference with the diff/patch approach is, that there are way less merge conflicts (git is smarter) and that the merge conflict are way easier to identify and they’re inline in the original files. Not to mention that when I would have fucked up I’d always have a way back.&lt;/p&gt;
&lt;p&gt;After I fixed the merge conflict, I &lt;code&gt;git update-index&lt;/code&gt; each conflicted file (to tell git it’s resolved) and &lt;code&gt;git rebase --continue&lt;/code&gt;-ed.&lt;/p&gt;
&lt;p&gt;Now I’ve got my updated wordpress in the &lt;code&gt;git&lt;/code&gt; folder. Then I backuped the current, copied over from git and visited &lt;code&gt;wp-admin/upgrade.php&lt;/code&gt; and I’m done :).&lt;/p&gt;
&lt;p&gt;By the way: “I didn’t say Subversion doesn’t work. Subversion users are just ugly and stupid.” — Linus on &lt;a href="http://www.youtube.com/watch?v=4XpnKHJAok8"&gt;this Google tech talk&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sidenote&lt;/strong&gt;, I switched from &lt;a href="http://wordpress-plugins.feifei.us/hashcash/"&gt;Hashcash&lt;/a&gt; to &lt;a href="http://akismet.com/"&gt;Akismet&lt;/a&gt;. Hashcash didn’t work anymore and Akismet theoretically should be the best solution because it isn’t based on security by obscurity.&lt;/p&gt;</description></item><item><title>Elastic tabstops plugins for gedit</title><link>https://blog.affien.com/archives/2007/05/28/elastic-tabstops-plugins-for-gedit/</link><pubDate>Mon, 28 May 2007 19:24:59 +0100</pubDate><guid>https://blog.affien.com/archives/2007/05/28/elastic-tabstops-plugins-for-gedit/</guid><description>&lt;p&gt;Spaces vs Tabs? Nah: &lt;a href="http://nickgravgaard.com/elastictabstops/"&gt;elastic tabstops&lt;/a&gt;, now &lt;a href="http://nickgravgaard.com/elastictabstops/#gedit"&gt;for gedit&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>The Future of the Internet</title><link>https://blog.affien.com/archives/2007/05/06/the-future-of-the-internet/</link><pubDate>Sun, 06 May 2007 18:07:41 +0100</pubDate><guid>https://blog.affien.com/archives/2007/05/06/the-future-of-the-internet/</guid><description>&lt;p&gt;One of the prominent people behind the current internet discusses the history (telephony, wire oriented), the current (IP, endpoint oriented) and the future (?, data oriented) &lt;a href="http://video.google.com/videoplay?docid=-6972678839686672840&amp;amp;hl=en"&gt;at google tech talks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A short synopsis: the internet is having trouble at the moment for it has been designed in a time the problem was different. In these days most of the data is duplicate data, which is a tremendous waste. Also connecting to the internet (getting an address) (and resulting from that keeping everything in sync) is hard. Van suggests and predicts a data oriented internet. A bit like a secure P2P bittorrent network, but instead of on top of IP on the IP level.&lt;/p&gt;
&lt;p&gt;It’s a very interesting talk, worth watching.&lt;/p&gt;</description></item><item><title>linux 2.6.21-bw</title><link>https://blog.affien.com/archives/2007/04/28/linux-2621-bw/</link><pubDate>Sat, 28 Apr 2007 20:11:53 +0100</pubDate><guid>https://blog.affien.com/archives/2007/04/28/linux-2621-bw/</guid><description>&lt;p&gt;There aren’t official reiser4 patches for .20 or .21. There are quite a few branches that contain support for reiser4, but these are highly unstable. (for instance the -mm tree). Also because I wanted to give &lt;a href="http://www.procode.org/stgit/"&gt;stacked git&lt;/a&gt; a shot, I started my own kernel tree:&lt;/p&gt;
&lt;p&gt;One big bzip2-ed diff: &lt;a href="http://w-nz.com/~darkshines/projects/bw-for-2.6.21.tar.bz2"&gt;bw-for-2.6.21.diff.bz2&lt;/a&gt;.&lt;br&gt;
bzip2-ed tar with the separate patches: &lt;a href="http://w-nz.com/~darkshines/projects/bw-for-2.6.21.tar.bz2"&gt;bw-for-2.6.21.tar.bz2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This release contains reiser4, suspend2, the gentoo patches and a few patches to get everything working together nicely.&lt;/p&gt;</description></item><item><title>Virtual package for your python application</title><link>https://blog.affien.com/archives/2007/04/21/virtual-package-for-your-python-application/</link><pubDate>Sat, 21 Apr 2007 19:45:06 +0100</pubDate><guid>https://blog.affien.com/archives/2007/04/21/virtual-package-for-your-python-application/</guid><description>&lt;p&gt;When you’ve got a big python application, you’ll usually split it up in modules. One big annoyance I’ve had is that a module inside a directory cannot (easily) import a module higher up in the tree. Eg: drawers/gtk.py cannot import state/bla.py.&lt;/p&gt;
&lt;p&gt;This is usually solved by making the application a package. This allows for &lt;code&gt;import myapp.drawers.gtk&lt;/code&gt; from everywhere inside your application. To make it a package though, you need to add the parent directory in the &lt;code&gt;sys.path&lt;/code&gt; list. But unfortunately this also includes all other subdirectories of the parent directory as packages.&lt;/p&gt;
&lt;p&gt;However, when the package module (eg: &lt;code&gt;myapp&lt;/code&gt;) was already loaded, then the path from which &lt;code&gt;myapp&lt;/code&gt; was loaded is used to find the submodules (eg: &lt;code&gt;myapp.drawers.gtk&lt;/code&gt;) and &lt;code&gt;sys.path&lt;/code&gt; isn’t looked at, at all. So, here is the trick:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;import sys
import os.path

p = os.path.dirname(__file__)
sys.path.append(os.path.abspath(p+&amp;#34;/..&amp;#34;))
__import__(os.path.basename(p))
sys.path.pop()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that this script doesn’t work when directly executed, because the &lt;code&gt;__file__&lt;/code&gt; attribute is only available when loaded as a module.&lt;/p&gt;
&lt;p&gt;Save this script as &lt;code&gt;loader.py&lt;/code&gt; in the root of your application. &lt;code&gt;import loader&lt;/code&gt; from the main script in your app, and you’ll be able to import modules by &lt;code&gt;myapp.a.module&lt;/code&gt;, where &lt;code&gt;myapp&lt;/code&gt; is the root directory name of your application.&lt;/p&gt;</description></item><item><title>This is How We Catch You Downloading</title><link>https://blog.affien.com/archives/2007/04/15/this-is-how-we-catch-you-downloading/</link><pubDate>Sun, 15 Apr 2007 14:38:52 +0100</pubDate><guid>https://blog.affien.com/archives/2007/04/15/this-is-how-we-catch-you-downloading/</guid><description>&lt;p&gt;torrentfreak.com has acquired a document how a british company is tracking down illegal use of P2P: &lt;a href="http://torrentfreak.com/this-is-how-we-catch-you-downloading/"&gt;This is How We Catch You Downloading&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Basically they use a modified P2P client which searches for infringing content, download it and if that works and is indeed is the content then they do a whois on your IP and send a infringement notice to your ISP. The best thing is that they claim that this provides enough proof that you really are infringing.&lt;/p&gt;
&lt;p&gt;They probably never heard about botnets.&lt;/p&gt;</description></item><item><title>Ruby and parenthesis</title><link>https://blog.affien.com/archives/2007/04/11/ruby-and-parenthesis/</link><pubDate>Wed, 11 Apr 2007 18:06:30 +0100</pubDate><guid>https://blog.affien.com/archives/2007/04/11/ruby-and-parenthesis/</guid><description>&lt;p&gt;Do you prefer&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p = Pathaname.new('.').realpath&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;p&gt;&lt;code&gt;p = (Pathname.new '.').realpath&lt;/code&gt;?&lt;/p&gt;</description></item><item><title>C&C 3 on Linux</title><link>https://blog.affien.com/archives/2007/04/01/cc-3-on-linux/</link><pubDate>Sun, 01 Apr 2007 15:20:10 +0100</pubDate><guid>https://blog.affien.com/archives/2007/04/01/cc-3-on-linux/</guid><description>&lt;p&gt;I’ve got &lt;em&gt;Command and Conquer 3: Tiberium Wars&lt;/em&gt; running on my Gentoo Linux installation with wine 0.9.34 by following the instructions &lt;a href="http://appdb.winehq.org/appview.php?iVersionId=7440"&gt;here&lt;/a&gt;. I had to first install it on windows though, and copy the folder for the installer didn’t work, even with Crossover Office.&lt;/p&gt;
&lt;p&gt;Except for (very glitchly) video and sometimes a crash everything seems to run. (Didn’t try multiplayer yet though). I had to put all quality settings to lowest, which makes me wonder whether that is my radeon X1400 being not so good as I expected or wine just being slow in emulating Direct3D.&lt;/p&gt;</description></item><item><title>The Filesystem Failed. Part I: introduction</title><link>https://blog.affien.com/archives/2007/03/03/the-filesystem-failed-part-i-introduction/</link><pubDate>Sat, 03 Mar 2007 19:12:12 +0100</pubDate><guid>https://blog.affien.com/archives/2007/03/03/the-filesystem-failed-part-i-introduction/</guid><description>&lt;p&gt;The Filesystem (I’ll consider the Linux VFS as an example) has failed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Database&lt;/em&gt; storage is implemented on top of the Filesystem, because the Filesystem is incapable of serving the needs of relational storage.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Metadata is stored inside files&lt;/em&gt; in many different formats which can only be guessed by clumsy ‘magic’ in the headers. This forces many media player and desktop search application to duplicate tag information in their own databases. Each of them has only limited support for each of the many different formats.&lt;/li&gt;
&lt;li&gt;More and more device and service abstractions are moving from the Filesystem &lt;em&gt;to seperate namespaces&lt;/em&gt;, because the Filesystem’s API is inadequate. Take for instance oss which used &lt;code&gt;/dev/dsp&lt;/code&gt;, whereas alsa uses its own. Many new abstractions don’t even go near the filesystem anymore, for instance kevents, futexes, networking, dbus and hal.&lt;/li&gt;
&lt;li&gt;Small files are stored in (compressed) &lt;em&gt;packs and archives&lt;/em&gt; because the Filesystem can’t handle them. This happens with for instance your mailbox.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem comes down to fragmentation of data and metadata in too many namespaces because the Filesystem doesn’t seem to be an adequate one.&lt;/p&gt;
&lt;p&gt;In a series of posts I’ll look at the possibilities to create one unified filesystem.&lt;/p&gt;</description></item><item><title>Watermarking media</title><link>https://blog.affien.com/archives/2007/03/01/watermarking/</link><pubDate>Thu, 01 Mar 2007 17:01:01 +0100</pubDate><guid>https://blog.affien.com/archives/2007/03/01/watermarking/</guid><description>&lt;p&gt;It seems the new trend of the music industry against piracy is watermarking movies/audio/etc.&lt;/p&gt;
&lt;p&gt;Content is water-marked by adding very small (unnoticeable) changes that could store something like a rsa based certificate to identify a given audiotrack.&lt;/p&gt;
&lt;p&gt;Originally I thought they’d use it to track down the source of an illegal download. It sounds illogical to me because it’s hard to keep watermarks when format is changed (mp3, ogg and others really do mess up slight unnoticeable differences because otherwise they wouldn’t compress as good). And when someone has got two versions of the same audiotrack one can compare them and find out how something is watermarked.&lt;/p&gt;
&lt;p&gt;Maybe the scheme of the industry isn’t that stupid, but the other way around (and a lot more evil). Maybe just sue everyone who hasn’t got a watermark on their movies or mp3.&lt;/p&gt;
&lt;p&gt;Luckily a Fair Use bill was passed which they say (haven’t checked) allows fair-use conversion of format of media.&lt;/p&gt;</description></item><item><title>Reiser4 for linux 2.6.20</title><link>https://blog.affien.com/archives/2007/02/25/reiser4-for-linux-2620/</link><pubDate>Sun, 25 Feb 2007 23:27:37 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/25/reiser4-for-linux-2620/</guid><description>&lt;p&gt;&lt;a href="http://w-nz.com/~darkshines/projects/reiser4-for-2.6.20-0.patch.gz"&gt;reiser4-for-2.6.20-0.patch.gz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Big fat warning&lt;/strong&gt;, when hibernating using suspend2 it seems to corrupt some memory here and there. So don’t hibernate.&lt;/p&gt;</description></item><item><title>Internal Microphone</title><link>https://blog.affien.com/archives/2007/02/11/internal-microphone/</link><pubDate>Sun, 11 Feb 2007 11:53:07 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/11/internal-microphone/</guid><description>&lt;p&gt;By accident, I discovered that my thinkpad has got an internal microphone. Now I can get rid of that stupid headset I have to use for skype.&lt;/p&gt;
&lt;p&gt;(Yeah, I know macBook’s have got a camera too)&lt;/p&gt;</description></item><item><title>4 inches</title><link>https://blog.affien.com/archives/2007/02/08/4-inches/</link><pubDate>Thu, 08 Feb 2007 21:38:30 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/08/4-inches/</guid><description>&lt;p&gt;Today several schools (including miine) stopped early because of ‘heavy’ snowfall. 10cm of snow, that are about 4 inches.&lt;/p&gt;
&lt;p&gt;It’s ridiculous.&lt;/p&gt;</description></item><item><title>Codeyard Community Day</title><link>https://blog.affien.com/archives/2007/02/03/codeyard-community-day/</link><pubDate>Sat, 03 Feb 2007 19:22:46 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/03/codeyard-community-day/</guid><description>&lt;p&gt;It was fun :).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeyard.net/fotos/communitydag-februari-2007.php?id=gallery&amp;amp;gcat=CommunitydagFebruari2007"&gt;Photo’s&lt;/a&gt;&lt;/p&gt;</description></item><item><title>ati-drivers-8.33.6 for Gentoo</title><link>https://blog.affien.com/archives/2007/02/02/ati-drivers-8336-for-gentoo/</link><pubDate>Fri, 02 Feb 2007 21:29:29 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/02/ati-drivers-8336-for-gentoo/</guid><description>&lt;p&gt;This is a slightly adjusted 25.3 ebuild that will give you the 8.33.6 ati-drivers for Gentoo. Yes, it’s dirty. They aren’t in the main tree yet because they are considered broken, although it works just fine for me.&lt;/p&gt;
&lt;p&gt;Download: &lt;a href="http://w-nz.com/~darkshines/projects/ati-drivers-overlay-8.33.6.tar.bz2"&gt;ati-drivers-overlay-8.33.6.tar.bz2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Extract them to an &lt;a href="http://gentoo-wiki.com/HOWTO_Installing_3rd_Party_Ebuilds"&gt;overlay&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;, the 8.33.6 drivers are &lt;em&gt;in the mainline tree now&lt;/em&gt;, so you should use those instead of mine.&lt;/p&gt;</description></item><item><title>Intel’s free literature</title><link>https://blog.affien.com/archives/2007/02/01/intels-free-literature/</link><pubDate>Thu, 01 Feb 2007 20:14:06 +0100</pubDate><guid>https://blog.affien.com/archives/2007/02/01/intels-free-literature/</guid><description>&lt;p&gt;I noticed that you are able to &lt;a href="http://www.intel.com/products/processor/manuals/index.htm"&gt;order hard-copy’s&lt;/a&gt; of Intel’s books on the IA-32, 64 and Itanium architecture. So I did.&lt;/p&gt;
&lt;p&gt;Today, a few days later, I received them. They’re very informative thorough and well structured. And, in contrary to other professional literature, you are able to read it without crunching your brains on one jargon-filled sentence. Basically free, dense and easily read books and great references.&lt;/p&gt;
&lt;p&gt;So, a big thank you to Intel for this nice free service.&lt;/p&gt;
&lt;p&gt;By the way, Itanium seems to really rock. (256 registers, compiler branch prediction, 8-superscalar, etc)&lt;/p&gt;
&lt;p&gt;Also, I’ve got no spare room anymore on my desk. 🙂&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2007/02/intelbooks1.JPG" title="intelbooks1.JPG"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2007/02/intelbooks1.thumbnail.JPG" alt="intelbooks1.JPG"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Python Imaging Library</title><link>https://blog.affien.com/archives/2007/01/30/python-imaging-library/</link><pubDate>Tue, 30 Jan 2007 00:54:39 +0100</pubDate><guid>https://blog.affien.com/archives/2007/01/30/python-imaging-library/</guid><description>&lt;p&gt;&lt;a href="http://www.pythonware.com/library/pil/"&gt;PIL&lt;/a&gt; is great. In less than a thousand lines one can compute the polygons from regions, assess the best possible subimage layout and create all the subimages.&lt;br&gt;
&lt;a href="http://blog.w-nz.com/wp-content/uploads/2007/01/npar3.png" title="npar3.png"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2007/01/npar3.thumbnail.png" alt="npar3.png"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Hashcash 3.2</title><link>https://blog.affien.com/archives/2007/01/03/hashcash-32/</link><pubDate>Wed, 03 Jan 2007 01:34:32 +0100</pubDate><guid>https://blog.affien.com/archives/2007/01/03/hashcash-32/</guid><description>&lt;p&gt;I upgraded to &lt;a href="http://elliottback.com/wp/archives/2005/10/23/wordpress-hashcash-30-beta/"&gt;hashcash 3.2&lt;/a&gt;. I hope that will stop the new wave of spam I had on this blog. When you’re upgrading yourself, note that now wp-hashcash resides in its own subdirectory in the plugins folder, I didn’t notice that and couldn’t find what was wrong until I noticed the ‘/wp-hashcash/’ bit in the source.&lt;/p&gt;
&lt;p&gt;By the way, happy new year!&lt;/p&gt;</description></item><item><title>Rotating Beryl cube using HDAPS on a Thinkpad</title><link>https://blog.affien.com/archives/2006/12/27/rotating-beryl-cube-using-hdaps-on-a-thinkpad/</link><pubDate>Wed, 27 Dec 2006 01:35:28 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/27/rotating-beryl-cube-using-hdaps-on-a-thinkpad/</guid><description>&lt;p&gt;I hacked together this little ruby script to read the G-measuring device in the Thinkpad’s harddisk (HDAPS) and rotate the desktop cube of Beryl when sudden movement occurs. A bit like what has been done for the MacBook already.&lt;/p&gt;
&lt;p&gt;http://w-nz.com/~darkshines/projects/rtollina.rb&lt;/p&gt;
&lt;p&gt;GPL, obviously. It’s not really perfect yet. I’ll try to improve it tomorrow and add support for compiz and maybe even make a little widget out of it.&lt;/p&gt;
&lt;p&gt;It’s based on &lt;a href="http://www.gnome.org/~fherrera/blog/gtollina.html"&gt;code by Fer&lt;/a&gt;, which is for Compiz instead of Beryl.&lt;/p&gt;</description></item><item><title>XGL take 2</title><link>https://blog.affien.com/archives/2006/12/27/xgl-take-2/</link><pubDate>Wed, 27 Dec 2006 00:01:22 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/27/xgl-take-2/</guid><description>&lt;p&gt;I tried to get AIGLX to work on my Thinkpad yesterday. AIGLX is an API similar to XGL, but is a better implementation. Unfortunately AIGLX requires implementation by the video-card driver (which is good because it allows more performance), but the proprietary drivers of ati still doesn’t support it. (nvidia’s do, note to myself: get nvidia next time).&lt;/p&gt;
&lt;p&gt;So I had to revert to XGL. A lot has changed since the last time I installed XGL. Other gentoo overlays, other windows managers, other hacks.&lt;/p&gt;
&lt;p&gt;I used the &lt;a href="http://wiki.gentoo-xeffects.org/Main_Page"&gt;gentoo-xeffects&lt;/a&gt; overlay to get Xgl.&lt;/p&gt;
&lt;p&gt;Installing Xgl was a lot more straight forward and less of a problem than it used to be. An emerge and writing a simple startxgl script was enough.&lt;/p&gt;
&lt;p&gt;The compiz-quinstorm patchset seems to have evolved to a proper branch of the compositing window manager, now called Beryl. It also includes a nice settings manager now.&lt;/p&gt;
&lt;p&gt;Even hibernation and suspend finally seem to work. 🙂&lt;/p&gt;
&lt;p&gt;A nice screenshot:&lt;br&gt;
&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/12/xgl4.png" title="xgl4.png"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/12/xgl4.thumbnail.png" alt="xgl4.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One thing left to do: integrate Xgl into xdm.&lt;/p&gt;</description></item><item><title>Avoiding multiple lock dead-locks by memory addresses</title><link>https://blog.affien.com/archives/2006/12/25/avoiding-multiple-lock-dead-locks-by-memory-addresses/</link><pubDate>Mon, 25 Dec 2006 20:18:43 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/25/avoiding-multiple-lock-dead-locks-by-memory-addresses/</guid><description>&lt;p&gt;Sometimes you need to lock several resources. If you don’t take great care you are likely to get yourself into dead-locks. A simple example with just two lockable resources A and B:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function foo {
 lock A;
 lock B;
 // Do something with A and B
 unlock A;
 unlock B;
}

function bar {
 lock B;
 lock A;
 // Do something different with A and B
 unlock B;
 unlock A;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; are called at about the same time then there is the change that &lt;code&gt;foo&lt;/code&gt; locks A and &lt;code&gt;bar&lt;/code&gt; locks B which will make &lt;code&gt;bar&lt;/code&gt; wait on &lt;code&gt;foo&lt;/code&gt;‘s lock on A and vice versa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution: fixed order on memory address&lt;/strong&gt;&lt;br&gt;
The simplest way to get rid of the deadlock is to always try to acquire a lock on A before on B. A generic solution would be to always lock the resource with the lowest memory address first.&lt;/p&gt;
&lt;p&gt;This only works when memory addresses are fixed or that there is an otherwise fixed order-able property.&lt;/p&gt;</description></item><item><title>(auto)mounting removable media as user</title><link>https://blog.affien.com/archives/2006/12/13/automounting-removable-media-as-user/</link><pubDate>Wed, 13 Dec 2006 18:46:26 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/13/automounting-removable-media-as-user/</guid><description>&lt;p&gt;I’ve always been bothered by the fact that you need to be root to mount anything (like an usb stick). It can be solved a bit by setting up udev rules and putting a specific device in &lt;code&gt;/etc/fstab&lt;/code&gt;, but that only works for &lt;em&gt;that&lt;/em&gt; single usb stick. Pretty annoying.&lt;/p&gt;
&lt;p&gt;Googling only gives you stupid and silly solution (like allowing users to mount &lt;code&gt;/dev/sd[a-z]&lt;/code&gt; — security risk).&lt;/p&gt;
&lt;p&gt;Luckily I’ve recently been pointed to &lt;a href="http://ivman.sourceforge.net/"&gt;ivman&lt;/a&gt;, which is an automounter. It automatically mounts removable media for you in &lt;code&gt;/media&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I looked at the internals of ivman, and noticed that it uses &lt;a href="http://www.piware.de/projects.shtml"&gt;pmount&lt;/a&gt;, which is a wrapper around mount which allows users to mount removable media on a &lt;code&gt;/media&lt;/code&gt; folder. Great!&lt;/p&gt;
&lt;p&gt;Btw, you need to be in the &lt;code&gt;plugdev&lt;/code&gt; group to use pmount.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update&lt;/em&gt; It seems that gnome-mount also works fine when you’re in the &lt;code&gt;plugdev&lt;/code&gt; group. Gnome-mount does about the same as pmount with the advantage that gnome-mount has got the nice gui integration everywhere in gnome.&lt;/p&gt;</description></item><item><title>Reiser4 for 2.6.19</title><link>https://blog.affien.com/archives/2006/12/09/reiser4-for-2619/</link><pubDate>Sat, 09 Dec 2006 16:23:23 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/09/reiser4-for-2619/</guid><description>&lt;p&gt;I found this patch: &lt;a href="http://laurent.riffard.free.fr/reiser4/reiser4-for-2.6.19.patch.gz"&gt;reiser4-for-2.6.19.patch.gz&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Disappearing backgrounds in IE.</title><link>https://blog.affien.com/archives/2006/12/08/disappearing-backgrounds-in-ie/</link><pubDate>Fri, 08 Dec 2006 18:33:14 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/08/disappearing-backgrounds-in-ie/</guid><description>&lt;p&gt;In Internet Explorer in some cases backgrounds disappear seemingly randomly. The fix? Add the &lt;code&gt;position: relative;&lt;/code&gt; style entry to the concerned &lt;code&gt;div&lt;/code&gt; tags.&lt;/p&gt;</description></item><item><title>Long mySQL keys</title><link>https://blog.affien.com/archives/2006/12/03/long-mysql-keys/</link><pubDate>Sun, 03 Dec 2006 23:58:03 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/03/long-mysql-keys/</guid><description>&lt;p&gt;Instead of limiting your long key (for instance a path) to approximately 800 characters (on mySQL with generic UTF8), you can hash your key and store the hash as index.&lt;/p&gt;
&lt;p&gt;The drawback is that you need to use a quite good hash function to avoid duplicates if you want to use it for a unique or primary key. These good hash functions tend to require some computing time.&lt;/p&gt;</description></item><item><title>md5(microtime())</title><link>https://blog.affien.com/archives/2006/12/03/md5microtime/</link><pubDate>Sun, 03 Dec 2006 23:52:50 +0100</pubDate><guid>https://blog.affien.com/archives/2006/12/03/md5microtime/</guid><description>&lt;p&gt;Don’t use &lt;code&gt;md5(microtime())&lt;/code&gt;. You might think it’s more secure than &lt;code&gt;md5(rand())&lt;/code&gt;, but it isn’t.&lt;/p&gt;
&lt;p&gt;With a decent amount of tries and a method of syncing (like a clock on your website) one can predict the result of &lt;code&gt;microtime()&lt;/code&gt; to the millisecond. This only leaves about a 1000 different possible return values for &lt;code&gt;microtime()&lt;/code&gt; to be guessed. That isn’t safe.&lt;/p&gt;
&lt;p&gt;Just stick with &lt;code&gt;md5(rand())&lt;/code&gt;, and if you’re lucky and &lt;code&gt;rand()&lt;/code&gt; is backed by &lt;code&gt;/dev/random&lt;/code&gt; you won’t even need the &lt;code&gt;md5()&lt;/code&gt;. In both cases it will be quite a lot more secure than using &lt;code&gt;microtime()&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>A loud present</title><link>https://blog.affien.com/archives/2006/11/27/a-loud-present/</link><pubDate>Mon, 27 Nov 2006 21:10:37 +0100</pubDate><guid>https://blog.affien.com/archives/2006/11/27/a-loud-present/</guid><description>&lt;p&gt;Today, a friend of mine, Gerben, gave me a birthday present (a tad late). Not the usual beverages (turned 18 ;)) (usual, but still very well appreciated :)), but a home-made portable speaker with built-in amplifier. Here seen making more sound than the internal speaker of my Thinkpad:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0050.jpg" title="dsc_0050.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0050.thumbnail.jpg" alt="dsc_0050.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It’s a nifty little device: it’s powered by either an internal battery or an external power source.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0048.jpg" title="dsc_0048.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0048.thumbnail.jpg" alt="dsc_0048.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It contains a voltage converter and a rectifier which allows a variable AC power source to be connected. This has been added to be able to connect the speaker to the electrical generator of a bicycle. Why? The previous version of this speaker was taken on the bicycle trip with a few friends to the Hertog Jan Brewery in Arcen (~70km) which was only powered by a battery (which tends to be exhausted).&lt;/p&gt;
&lt;p&gt;Even better, when set into external source mode it recharges the battery. And because of the voltage converter, the sound doesn’t get louder when you are cycling faster, but the quality of the sound gets better!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0051.jpg" title="dsc_0051.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0051.thumbnail.jpg" alt="dsc_0051.jpg"&gt;&lt;/a&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0049.jpg" title="dsc_0049.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0049.thumbnail.jpg" alt="dsc_0049.jpg"&gt;&lt;/a&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0047.jpg" title="dsc_0047.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/11/dsc_0047.thumbnail.jpg" alt="dsc_0047.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ve had quite some fun dissecting the little device. Thanks again Gerben!&lt;/p&gt;</description></item><item><title>P’tit-doux</title><link>https://blog.affien.com/archives/2006/11/20/ptit-doux/</link><pubDate>Mon, 20 Nov 2006 23:14:02 +0100</pubDate><guid>https://blog.affien.com/archives/2006/11/20/ptit-doux/</guid><description>&lt;p&gt;For my dutch readers, a great analogy between microsoft and a fictional P’tit-doux.&lt;br&gt;
&lt;a href="http://www.vromans.org/johan/articles/ptitdoux.html"&gt;&lt;br&gt;
http://www.vromans.org/johan/articles/ptitdoux.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Simple Branch Prediction Analysis</title><link>https://blog.affien.com/archives/2006/11/19/simple-branch-prediction-analysis/</link><pubDate>Sun, 19 Nov 2006 16:08:27 +0100</pubDate><guid>https://blog.affien.com/archives/2006/11/19/simple-branch-prediction-analysis/</guid><description>&lt;p&gt;This &lt;a href="http://eprint.iacr.org/2006/351"&gt;paper&lt;/a&gt; outlines simple branch prediction analysis attack against the RSA decryption algorithm.&lt;/p&gt;
&lt;p&gt;At the core of RSA decryption is a loop over all bits of the secret key number &lt;code&gt;d&lt;/code&gt;. When the bit 1 there is other code executed than when the bit is 0. The CPU branches on a different bit.&lt;/p&gt;
&lt;p&gt;A spy process can be run on the CPU which measures the branch cache of the CPU by flooding the cache with branches and measuring the time it takes. When the sequentially running secret process doing RSA decryption makes a different branch (1 instead of 0) it can be noticed in a change of execution time on the spy process’s branches.&lt;/p&gt;
&lt;p&gt;In this way quite a lot of secret bits can be derived.&lt;/p&gt;
&lt;p&gt;There are some clear &lt;em&gt;buts&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You must be able to insert a spy process on the computer itself and it should know exactly when the RSA process runs.&lt;/li&gt;
&lt;li&gt;To attain clear readings, there shouldn’t be other processes claiming too much CPU time.&lt;/li&gt;
&lt;li&gt;The spy and CPU process should run on the same physical processor and preferably at the same time (dual core)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An easy fix would be to allocate a whole processor for the RSA decryption time, so no process can spy. Another option would be to add noise in the Branch Prediction Buffer, but that would result in a performance loss.&lt;/p&gt;</description></item><item><title>E-Mail server issues</title><link>https://blog.affien.com/archives/2006/11/09/e-mail-server-issues/</link><pubDate>Thu, 09 Nov 2006 23:12:42 +0100</pubDate><guid>https://blog.affien.com/archives/2006/11/09/e-mail-server-issues/</guid><description>&lt;p&gt;I had some problems with a recent mysql update — it broke some packages including qmail-send, which caused quite a lot of mail to be dropped the last few days. Sorry for that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: mail was fortunately not dropped :), it’s still in the qmail queue, it just hasn’t been delivered yet. So there’ll only be a delay.&lt;/p&gt;</description></item><item><title>RTFM, where?</title><link>https://blog.affien.com/archives/2006/10/27/rtfm-where/</link><pubDate>Fri, 27 Oct 2006 08:24:03 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/27/rtfm-where/</guid><description>&lt;p&gt;Recently a buddy on msn asked me a linux question, he just started linux so he had some problems getting stuff done.&lt;/p&gt;
&lt;p&gt;He downloaded an installer, he said, a .run, but he doesn’t know how to execute it. He tried googling for it and asking on forums, but didn’t get an answer, so he asked me.&lt;/p&gt;
&lt;p&gt;I solved his problem, but I still wondered, where you can find that you need to put ‘./’ in front of a file in bash to execute it and where can you find that you probably need to &lt;code&gt;chmod +x&lt;/code&gt; the file too if you downloaded it from somewhere, if you are a total newcomer to linux.&lt;/p&gt;
&lt;p&gt;The bash tutorial would’ve probably solved it, but do you know that that thing in which you are typing actually is a separate program? Probably not.&lt;/p&gt;
&lt;p&gt;I basically learned all this trivial stuff while following the gentoo installation manual, but I guess that’s a bit too much to ask from each new linux user. There should be a good linux introduction that explains this trivial stuff somewhere to which I can redirect new users. Anyone knows one?&lt;/p&gt;</description></item><item><title>Reiser4 on 2.6.18</title><link>https://blog.affien.com/archives/2006/10/27/reiser4-on-2618/</link><pubDate>Fri, 27 Oct 2006 00:41:31 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/27/reiser4-on-2618/</guid><description>&lt;p&gt;Try this patch: &lt;a href="http://vipernicus.evolution-mission.org/patches/2.6.18/emission1/patches/04-reiser4-2.6.18-mm2.patch"&gt;&lt;br&gt;
http://vipernicus.evolution-mission.org/…&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Fallacies (1)</title><link>https://blog.affien.com/archives/2006/10/17/fallacies-1/</link><pubDate>Tue, 17 Oct 2006 13:38:11 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/17/fallacies-1/</guid><description>&lt;p&gt;I just read this on slashdot:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;statistically significant relationship between autism rates and television watching&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Offcourse this &lt;em&gt;relation&lt;/em&gt; was explained as televisions causing children to become autistic. This is a very annoying fallacy. Why? Because &lt;em&gt;just maybe&lt;/em&gt; children with autism like to watch television more than other children.&lt;/p&gt;
&lt;p&gt;If there is a relation, and if it’s not coincidental, there are still two ways to explain it as a cause and effect relation — you cant just blindly assume that one of the two is the cause.&lt;/p&gt;
&lt;p&gt;Same goes with relations like:&lt;/p&gt;
&lt;p&gt;“Children that play violent games are more likely to become criminals” or “Children that are to become criminals are more likely to play games”&lt;/p&gt;
&lt;p&gt;Stupid shout culture.&lt;/p&gt;</description></item><item><title>Good and bad CAPTCHA`s</title><link>https://blog.affien.com/archives/2006/10/15/good-and-bad-captchas/</link><pubDate>Sun, 15 Oct 2006 12:02:25 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/15/good-and-bad-captchas/</guid><description>&lt;p&gt;CAPTCHA’s are images which content needs to be written into a textbox by a user to make sure it’s a human instead of some computer script. This is an example of a good CAPTCHA of yahoo:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/yahoo53.thumbnail.jpeg" alt="yahoo53.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;This is an example of a really bad CAPTCHA:&lt;br&gt;
&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dotmac18.thumbnail.jpeg" alt="dotmac18.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;What makes a CAPTCHA good, as in hard to solve by a computer? Lets look how a computer would solve a CAPTCHA, there basically are 3 parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove rubish background.&lt;/li&gt;
&lt;li&gt;Remove rubish lines and partition the image into sections, with in each section a letter.&lt;/li&gt;
&lt;li&gt;Recognize the letter with a neural network.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Part 1 is very easy in most cases — just filter everything out that isn’t black and isn’t a glyph-ic curve. It gets a bit more difficult if the font and background colors are random, but usually it’s simple to distinguish between a glyph (small, curve-ish, solid color) and a background (solid, usually gradients). Software is way better in this step than humans.&lt;/p&gt;
&lt;p&gt;Part 2 is the most difficult part for software. Distorting fonts isn’t that much of a problem, as long as the software can recognize seperate curve-blobs. The real problem comes in when there are red-hering-curves or when several glyphs are connected with curves like in the yahoo CAPTCHA. When the captcha uses undistorted fixed aligned fonts, it isn’t a problem even if you add glyph connecting curves like in the dotmac CAPTCHA, because you only need to add a little bit of code to recognize an authentic glyph curve (small, thin) and then you can predict the position of the other curves. Humans are better in this step than computers.&lt;/p&gt;
&lt;p&gt;Part 3 is a bit tedious for software, but usually easier for specifically trained &lt;a href="http://en.wikipedia.org/wiki/Neural_Network"&gt;neural networks&lt;/a&gt; than for humans.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to make a good CAPTCHA&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not add stupid background or differently coloured polygons, they won’t work at all — they will only confuse the human.&lt;/li&gt;
&lt;li&gt;Do not use a fixed font, size or alignment. Rotate the font a bit, transform it a bit and, most importantly, place them unpredictably.&lt;/li&gt;
&lt;li&gt;Add glyph like curves the intersect preferably only two glyphs to make them less recognizable. Take care though that you don’t make them too font like, because that’ll prevent the human from recognizing. These extra intersecting curves make CAPTCHA’s strong, because it prevents proper partitioning.&lt;/li&gt;
&lt;li&gt;Don’t use strange fonts that might seem hard to see, but are easy recognizable. For instance, dotted fonts are very easy to locate when everything else are solid curves.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; nice blogpost on breaking captcha’s: &lt;a href="http://www.brains-n-brawn.com/default.aspx?vDir=aicaptcha"&gt;http://www.brains-n-brawn.com/default.aspx?vDir=aicaptcha&lt;/a&gt;&lt;/p&gt;</description></item><item><title>T60 (2)</title><link>https://blog.affien.com/archives/2006/10/07/t60-2/</link><pubDate>Sat, 07 Oct 2006 23:57:57 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/07/t60-2/</guid><description>&lt;p&gt;After 2 days installing gentoo on my great T60 I’ve accomplished quite a lot so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WiFi works. 4 seperate components (userland, firmware, kernel module and yet another kernel module) increase complexity a bit. Although the fifth component caused trouble — I forgot to tweak &lt;code&gt;conf.d/net&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Radeon X1400 and video card worked almost directly after using &lt;code&gt;aticonf&lt;/code&gt; — nice! When I upgraded to &lt;code&gt;xorg-server-1.1&lt;/code&gt;, though, I got a few crashes when closing X in a not-so-nice manner.&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;synaptics&lt;/code&gt; drivers my touchpad now support drag’n’drop, right and middle mouse click and scrolling emulation. Still got to find a way to bind the thinkpad shortcut to disable/enable the point or pad.&lt;/li&gt;
&lt;li&gt;Finally got the DVD rewriter to work. It seems I overlooked one little stupid generic E-IDE option in the kernel config.&lt;/li&gt;
&lt;li&gt;Bluetooth and infrared should work — haven’t got the gadgets to try them out&lt;/li&gt;
&lt;li&gt;Never even saw a PCCard, so didn’t even bother to look into ti&lt;/li&gt;
&lt;li&gt;Software suspend (hibernation) doens’t work yet, but I definitely be working on that.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>T60</title><link>https://blog.affien.com/archives/2006/10/05/t60/</link><pubDate>Thu, 05 Oct 2006 20:47:39 +0100</pubDate><guid>https://blog.affien.com/archives/2006/10/05/t60/</guid><description>&lt;p&gt;I just received the &lt;a href="http://www.pro-com.org/NOFOST.de/Pages/ArticleDetails.aspx?ArticleID=1535&amp;amp;BackUrl=438385793"&gt;Thinkpad T60 notebook&lt;/a&gt; I ordered last week from &lt;a href="http://nofost.de/"&gt;nofost.de&lt;/a&gt;. And I’m thrilled!&lt;/p&gt;
&lt;p&gt;I’ve been busy all day installing gentoo on the beauty (and removing the ugly windows sticker).&lt;/p&gt;
&lt;p&gt;Some nice pictures:&lt;br&gt;
&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0026.jpg" title="dsc_0026.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0026.thumbnail.jpg" alt="dsc_0026.jpg"&gt;&lt;/a&gt; &lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0024.jpg" title="dsc_0024.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0024.thumbnail.jpg" alt="dsc_0024.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0023.jpg" title="dsc_0023.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0023.thumbnail.jpg" alt="dsc_0023.jpg"&gt;&lt;/a&gt; &lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0022.jpg" title="dsc_0022.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0022.thumbnail.jpg" alt="dsc_0022.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0025.jpg" title="dsc_0025.jpg"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/10/dsc_0025.thumbnail.jpg" alt="dsc_0025.jpg"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>New google reader</title><link>https://blog.affien.com/archives/2006/09/29/new-google-reader/</link><pubDate>Fri, 29 Sep 2006 18:24:10 +0100</pubDate><guid>https://blog.affien.com/archives/2006/09/29/new-google-reader/</guid><description>&lt;p&gt;&lt;a href="http://www.google.com/reader/view/"&gt;Google Reader&lt;/a&gt; has been updated. It resembles &lt;a href="http://www.bloglines.com/"&gt;bloglines&lt;/a&gt; a bit more concerning the tree view. It has still got the usual items by popularity/date view as the “all items” view. It’s looks nicer and seems to work pretty well.&lt;br&gt;
&lt;a href="http://blog.w-nz.com/archives/2006/09/29/new-google-reader/screenshot-google-reader-mozilla-firefoxpng/" title="screenshot-google-reader-mozilla-firefox.png"&gt;&lt;img src="http://blog.w-nz.com/wp-content/uploads/2006/09/screenshot-google-reader-mozilla-firefox.thumbnail.png" alt="screenshot-google-reader-mozilla-firefox.png"&gt;&lt;/a&gt;&lt;br&gt;
One thing still bothers me: the load times. Sometimes it’s just slow (same with gmail). It’s annoying.&lt;/p&gt;</description></item><item><title>18</title><link>https://blog.affien.com/archives/2006/08/30/18/</link><pubDate>Wed, 30 Aug 2006 09:37:20 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/30/18/</guid><description>&lt;p&gt;My brother and I turned 18 today!&lt;/p&gt;
&lt;p&gt;Feel free to visit us today and have some coffee and a slice of pie.&lt;/p&gt;
&lt;p&gt;Send a mail to x@y, or call 024 6421829 (in holland). &lt;small&gt;Where x=&lt;code&gt;bas.westerbaan&lt;/code&gt; and y=&lt;code&gt;gmail.com&lt;/code&gt;&lt;/small&gt;&lt;/p&gt;</description></item><item><title>Arcen</title><link>https://blog.affien.com/archives/2006/08/18/arcen/</link><pubDate>Fri, 18 Aug 2006 01:14:36 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/18/arcen/</guid><description>&lt;p&gt;Last tuesday I cycled with some friends (about 11) to Arcen to visit the &lt;a href="http://www.hertogjan.nl/index.htm"&gt;Hertog Jan&lt;/a&gt; &lt;a href="http://www.bus-idee.nl/fietser%20brouwerij.jpg"&gt;brewery&lt;/a&gt;. The ~75km of cycling went pretty well — way better than expected. We stayed on a 4 star camping for the night and cycled back the next day.&lt;/p&gt;
&lt;p&gt;Needless to say, this was a great experience and we all had a lot of fun.&lt;/p&gt;
&lt;p&gt;Some photos were made, I’ll post them as soon as I get them.&lt;/p&gt;</description></item><item><title>WP 2.0.4</title><link>https://blog.affien.com/archives/2006/08/18/wp-204/</link><pubDate>Fri, 18 Aug 2006 01:03:47 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/18/wp-204/</guid><description>&lt;p&gt;Upgraded to &lt;a href="http://wordpress.org/development/2006/07/wordpress-204/"&gt;WordPress 2.0.4&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As usual, slam the F5 button (or similar) once (or twice on stupid browsers) to invalidate the old stylesheets and images in the cache. If your browser is really stupid (*cough* IE *cough*), you might need to purge the whole cache manually, but that isn’t my concern ;-).&lt;/p&gt;</description></item><item><title>bcmap 0.1</title><link>https://blog.affien.com/archives/2006/08/13/bcmap-01/</link><pubDate>Sun, 13 Aug 2006 18:41:33 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/13/bcmap-01/</guid><description>&lt;p&gt;&lt;code&gt;bcmap&lt;/code&gt; is a simply program to be linked against klibc to map Broadcom RAIDCORE disks to more sensible and stable device nodes.&lt;/p&gt;
&lt;p&gt;Currently the bcraid drivers assign the next available &lt;code&gt;sd&lt;/code&gt; node to a detected disk, which is very inconvenient when you have a usb stick inserted on boot which pushes your root disk from &lt;code&gt;sda&lt;/code&gt; to &lt;code&gt;sdb&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;bcmap ensures that your first array will always be &lt;code&gt;/dev/bca&lt;/code&gt;, which is a nice thing.&lt;/p&gt;
&lt;p&gt;&amp;gt;&amp;gt;&amp;gt; &lt;a href="http://w-nz.com/~darkshines/projects/bcmap-0.1.tar.bz2"&gt;bcmap-0.1.tar.bz2&lt;/a&gt; (source code)&lt;/p&gt;
&lt;p&gt;Licensed under the (holy) GNU GPL v.2&lt;/p&gt;</description></item><item><title>bcraid drivers part two</title><link>https://blog.affien.com/archives/2006/08/05/bcraid-drivers-part-two/</link><pubDate>Sat, 05 Aug 2006 14:31:12 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/05/bcraid-drivers-part-two/</guid><description>&lt;p&gt;Here’s a small patch that tweak the broadcom raid drivers for the bc4000 series to run on the latest kernels:&lt;/p&gt;
&lt;p&gt;http://w-nz.com/~darkshines/projects/bcraid-2.1.0-bw1.patch&lt;/p&gt;
&lt;p&gt;Note that it is everything but complete. Some other pointers getting the bcraid to work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use sparse memory or conitguous memory instead of incontiguous memory in the memory layout configuration in the kernel. (&lt;code&gt;CONFIG_SPARSEMEM=y&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Enable the magic sysrq key (&lt;code&gt;CONFIG_MAGIC_SYSRQ=y&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the moment I’m trying to get the bcraid module working in an initrd to allow the root partition on the raid drivers.&lt;/p&gt;</description></item><item><title>Oops</title><link>https://blog.affien.com/archives/2006/08/03/oops/</link><pubDate>Thu, 03 Aug 2006 07:49:42 +0100</pubDate><guid>https://blog.affien.com/archives/2006/08/03/oops/</guid><description>&lt;p&gt;The &lt;code&gt;mysql&lt;/code&gt; wasn’t enabled whilest updating &lt;code&gt;dev-lang/php&lt;/code&gt;. This caused a big part of my website to fail to operate any longer after the update. I enabled and re-emerged and everything works fine again. Sorry ’bout the downtime.&lt;/p&gt;</description></item><item><title>The rm -r / typo</title><link>https://blog.affien.com/archives/2006/07/27/the-rm-r-typo/</link><pubDate>Thu, 27 Jul 2006 18:01:21 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/27/the-rm-r-typo/</guid><description>&lt;p&gt;Today I accidently made a (yes, very stupid) typo in a root console:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rm -r /&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I noticed the typo almost directly, but &lt;code&gt;rm&lt;/code&gt; managed to wipe out my &lt;code&gt;/bin&lt;/code&gt; and started removing parts of &lt;code&gt;/boot&lt;/code&gt;. This situation wasn’t very helpful for the stability of my system, as you might understand.&lt;/p&gt;
&lt;p&gt;For the windows user: it’s a bit like deleting half of all executables in the windows folder.&lt;/p&gt;
&lt;p&gt;One key difference: when running linux, you can fix it easily. I booted a livecd, &lt;code&gt;mount&lt;/code&gt;ed my system, copied the &lt;code&gt;/bin&lt;/code&gt; from a stage3 tarball to my root partition and rebooted.&lt;/p&gt;
&lt;p&gt;And it’s working again! There were some complaints about a libproc version mismatch with the binaries, but that’ll be easily solved by a &lt;code&gt;emerge -e system&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You just got to love linux. (and other nixes for that matter)&lt;/p&gt;</description></item><item><title>SINP: Push versus Pull</title><link>https://blog.affien.com/archives/2006/07/27/sinp-push-versus-pull/</link><pubDate>Thu, 27 Jul 2006 15:10:43 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/27/sinp-push-versus-pull/</guid><description>&lt;p&gt;SINP is &lt;em&gt;pull&lt;/em&gt; based — I give my SINP address to someone, and he will &lt;em&gt;pull&lt;/em&gt; the information he wants from my SINP server.&lt;/p&gt;
&lt;p&gt;Our competitor &lt;a href="http://www.sxip.org/"&gt;SXIP&lt;/a&gt; is &lt;em&gt;push&lt;/em&gt; based. When I use my SXIP identity I push all information I want to provide to the service — there doesn’t even have to be a SXIP server (‘homesite’).&lt;/p&gt;
&lt;p&gt;Push has got certain advantages over pull:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull is &lt;em&gt;complexer&lt;/em&gt;: you need more traffic and more complicated traffic. Push is &lt;em&gt;simpler&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;You most likely need a seperate server for pull (you need one with SINP at least), this makes you rely on your SINP server. You don’t need a real one for push.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But pull too got advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You don’t need to actively give your information. When I’m offline someone can still pull information from my SINP identity.&lt;/li&gt;
&lt;li&gt;Pull doesn’t require the actual information to go via your computer. If someone requests my creditcard number and I allow it, it won’t be redirected through the computer I’m using, which is safer.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Tilda</title><link>https://blog.affien.com/archives/2006/07/22/tilda/</link><pubDate>Sat, 22 Jul 2006 18:59:12 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/22/tilda/</guid><description>&lt;p&gt;&lt;a href="http://tilda.sourceforge.net/"&gt;Tilda&lt;/a&gt; is a drop-down terminal for linux. Press the assigned hotkey and the terminal will dropdown and gains focus, press it once again and it’ll dropout. And even better, the terminal isn’t closed, just hidden.&lt;/p&gt;
&lt;p&gt;This is great for development. I write some code, press Ctrl+S to save, Alt+Q for the terminal and make. If there is a bug I can Alt+Q and return to my code, and if I didn’t look closely enough I can press Alt+Q again to see the output again in the terminal.&lt;/p&gt;</description></item><item><title>SINP Certificates and redirects</title><link>https://blog.affien.com/archives/2006/07/19/sinp-certificates-and-redirects/</link><pubDate>Wed, 19 Jul 2006 13:24:59 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/19/sinp-certificates-and-redirects/</guid><description>&lt;p&gt;Tuesday the 11th, we (Noud, Bram and I) had a meeting with some guys of the Security of Systems Group at the Radboud University. We discussed the security of the current SINP protocol. There hasn’t been a hard verdict on whether SINP is secure, because the SINP specification leaves a lot of details to implementations and SINP doesn’t make hard claims on its security yet (which can be either proved or disproved).&lt;/p&gt;
&lt;p&gt;The meeting has yielded two new additions to SINP: document certificates&lt;sup&gt;1&lt;/sup&gt; and redirects.&lt;/p&gt;
&lt;p&gt;First of, &lt;strong&gt;SINP document certificates&lt;/strong&gt;. At the moment you can’t trust the information in a SINP document. I can forge my SINP document and claim that I’m Belgium, which I am not. To allow some trust which some people and services care about, we’ll allow certificates in your identity document. Basically you let someone sign a part of your SINP document and include that certificate.&lt;/p&gt;
&lt;p&gt;Your goverment could sign your name in your SINP document for instance and you’d add that certificate into your document, which could be required by some services. These certificates are a bit tricky though to design, because they do need to be secure and they need to be a bit more dynamic than your usual certificate because of the way SINP documents are queried.&lt;/p&gt;
&lt;p&gt;A second problem we encountered during the meeting was how to be able to trust your SINP server. I (and other tech savvy people) can set up their own SINP server, which we can fully trust because we set it up ourselves. Not so tech savvy people can’t — they need to rely on existing SINP servers. &lt;em&gt;The problem is whether we can trust those servers with our secrets.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Cees (if I recall correctly) coined the idea that some of your secrets are already on the internet. If you’ve got a VISA creditcard number, then VISA obviously has that creditcard number, and you trust them with it. What if VISA would store the part of your SINP identity document with your creditcardnumber on its own SINP Server?&lt;/p&gt;
&lt;p&gt;Basically I go to a big SINP provider (which I don’t trust), I create a SINP identity and put in my SINP document that you can find my creditcard number under the SINP identity &lt;code&gt;bas@visa.com&lt;/code&gt;. This act of redirecting clients to other SINP identities is called a &lt;strong&gt;SINP Redirect&lt;/strong&gt;. SINP Redirects could also proof very usefull when you change your SINP server. The only thing you’d have to do is to set up a SINP redirect in your old identity document to your new identitiy document.&lt;/p&gt;
&lt;p&gt;Both &lt;em&gt;SINP Certificates&lt;/em&gt; and &lt;em&gt;SINP Redirects&lt;/em&gt; will require a lot of though to implement cleanly and simple, which is tricky.&lt;/p&gt;
&lt;p&gt;Any thoughts would be welcome.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;1: Actually, this certificates aren’t new, Bram came up with the idea quite a while ago.&lt;/small&gt;&lt;/p&gt;</description></item><item><title>Typed Yields: Non fatal exceptions</title><link>https://blog.affien.com/archives/2006/07/16/typed-yields-non-fatal-exceptions/</link><pubDate>Sun, 16 Jul 2006 17:50:23 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/16/typed-yields-non-fatal-exceptions/</guid><description>&lt;p&gt;Wouldn’t it be nice to have:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;begin {&lt;br/&gt;
&amp;amp;nsbrLoadTheDatabase(&amp;quot;foo.bar&amp;quot;);&lt;br/&gt;
} rescue (Exception e) {&lt;br/&gt;
print &amp;quot;Fatal exception happened: &amp;quot;, e&lt;br/&gt;
} on (Warning w) {&lt;br/&gt;
print &amp;quot;Database Warning: &amp;quot;, w&lt;br/&gt;
} on (Message m) {&lt;br/&gt;
print &amp;quot;Database Message: &amp;quot;, m&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;rescue (Exception e)&lt;/code&gt; should be familiar with everyone — something failed, maybe the database file was corrupted very bad, and raised an exception and the &lt;code&gt;rescue&lt;/code&gt; block will be executed.&lt;/p&gt;
&lt;p&gt;But what if the database has a small error, or something is only a little bit out of place. You wouldn’t want to just ignore it, but warn about it. Usually one would implement a ‘Logger’ class to which a function can log certain events, but that is ugly and inconvenient.&lt;/p&gt;
&lt;p&gt;Enter &lt;em&gt;non fatal exceptions&lt;/em&gt;. Basically there would be two ways to raise an exception, fatal like we all know it, and non fatal. When the &lt;code&gt;on&lt;/code&gt; block for a non fatal exception has been executed, control will be returned to the function in which the &lt;code&gt;raise&lt;/code&gt; was called.&lt;/p&gt;
&lt;p&gt;This is done in about the same ways as a lot of languages implement &lt;code&gt;yield&lt;/code&gt;. But this time the handling code depends on the type of the yielded object.&lt;/p&gt;
&lt;p&gt;As far as Kaja and I concern this will be a feature of Paradox.&lt;/p&gt;
&lt;p&gt;Thanks go to Bram for the idea.&lt;/p&gt;</description></item><item><title>sinp.rb</title><link>https://blog.affien.com/archives/2006/07/03/sinprb/</link><pubDate>Mon, 03 Jul 2006 00:30:49 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/03/sinprb/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;irb&amp;gt; &lt;strong&gt;require 'sinp'&lt;/strong&gt;&lt;br/&gt;
irb&amp;gt; &lt;strong&gt;c = SINP::Client.new nil, nil, [:http]&lt;/strong&gt;&lt;br/&gt;
irb&amp;gt; &lt;strong&gt;c.getPublicDocument('Kristy@w-nz.com').write&lt;/strong&gt;&lt;br/&gt;
&amp;lt;requested version='2'&amp;gt;&lt;br/&gt;
&amp;lt;sinp-id&amp;gt;&lt;br/&gt;
&amp;lt;name&amp;gt;&amp;lt;nick&amp;gt;kristy&amp;lt;/nick&amp;gt;&amp;lt;/name&amp;gt;&lt;br/&gt;
&amp;lt;address type='email'&amp;gt;kbuiter@hotmail.com&amp;lt;/address&amp;gt;&lt;br/&gt;
&amp;lt;uri&amp;gt;hotmail.com&amp;lt;/uri&amp;gt;&lt;br/&gt;
&amp;lt;/sinp-id&amp;gt;&lt;br/&gt;
&amp;lt;/requested&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can see, I’ve almost finished the implementation of a Ruby SINP client — I only got to finish SINP Negotiation.&lt;/p&gt;</description></item><item><title>SINP</title><link>https://blog.affien.com/archives/2006/07/01/sinp/</link><pubDate>Sat, 01 Jul 2006 12:51:59 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/01/sinp/</guid><description>&lt;p&gt;SINP is a protocol based on HTTP(S) and XML that provides you with an &lt;strong&gt;identity&lt;/strong&gt; on the web. You register a so called &lt;em&gt;SINP Identity&lt;/em&gt; on a &lt;em&gt;SINP Server&lt;/em&gt; of your choice. To address a certain identity, we use an email like notation: &lt;code&gt;bas@w-nz.com&lt;/code&gt; is the SINP Identity of the user &lt;code&gt;bas&lt;/code&gt; on the SINP Server &lt;code&gt;w-nz.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The first big feature of SINP is &lt;strong&gt;authentication&lt;/strong&gt;. If someone claims to be &lt;code&gt;bram@w-nz.com&lt;/code&gt;, I can check that by asking &lt;code&gt;w-nz.com&lt;/code&gt; to check it. I’ll redirect that guy to &lt;code&gt;w-nz.com&lt;/code&gt; to let him be checked by his proclaimed SINP Server. If he really is &lt;code&gt;bram@w-nz.com&lt;/code&gt;, he’ll have a nice session cookie for &lt;code&gt;w-nz.com&lt;/code&gt; and &lt;code&gt;w-nz.com&lt;/code&gt; will check that. After that &lt;code&gt;w-nz.com&lt;/code&gt; will redirect him back and I’ll ask &lt;code&gt;w-nz.com&lt;/code&gt; whether he succeeded.&lt;/p&gt;
&lt;p&gt;One major application of this authentication is that someone who posts a blog comment as &lt;code&gt;noud@w-nz.com&lt;/code&gt;, really is/are the same guy(s) that posted before as &lt;code&gt;noud@w-nz.com&lt;/code&gt;, for they are allowed by &lt;code&gt;w-nz.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second big feature of SINP is that each identity comes bundled with a XML &lt;strong&gt;document&lt;/strong&gt;, which can store information about the owner like his name, email address, date of birth, etc. The SINP Server stores this document. The &lt;em&gt;identity owner&lt;/em&gt;, the guy who owns the identity, can pick an access policy for each little bit of information in this document. You might want to share your real address only to those who you’ve explicitly allowed. Everyone can see the parts of your document you’ve allowed everyone access to. &lt;a href="https://w-nz.com/sinp/users/bas"&gt;This is the one for bas@w-nz.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get specific parts instead of the whole thing, or get to stuff you’ve limited access to, one needs to use &lt;strong&gt;SINP Negotiation&lt;/strong&gt;. To get some specific information from &lt;code&gt;noud@w-nz.com&lt;/code&gt;, I ask &lt;code&gt;w-nz.com&lt;/code&gt; for this specific information, in the form of a few xpaths. Along with the xpaths I can send my own SINP address, &lt;code&gt;bas@w-nz.com&lt;/code&gt;. The server will respond on each request according to the access policy which the SINP Server has set. There are several possibilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ok&lt;/strong&gt;, the requested information will be included in the response.&lt;/li&gt;
&lt;li&gt;Nope, you’re &lt;strong&gt;denied&lt;/strong&gt; access to that.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not found&lt;/strong&gt;, that stuff isn’t in this document.&lt;/li&gt;
&lt;li&gt;You’ll have to &lt;strong&gt;ask&lt;/strong&gt; Noud. Basically you’ll have to redirect Noud to the server, where he will be authenticated and after that he can decide whether to allow you access to it, and you can try again lateron.&lt;/li&gt;
&lt;li&gt;If you’re &lt;code&gt;bas@w-nz.com&lt;/code&gt;, you can see it. You’ll have to &lt;strong&gt;authenticate&lt;/strong&gt;, though. This is done via sinp authentication as described before.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another big feature of SINP is versioning, which allows &lt;strong&gt;caching&lt;/strong&gt;. The version of a specific bit of information is send back on each response in negotiation. In a negotation request, I can specify the current version I already have. In case that specific part of the document hasn’t updated, the SINP server will let me know, instead of sending the whole thing.&lt;/p&gt;
&lt;p&gt;One advantage of caching and negotation is that information can be kept &lt;strong&gt;synchronized&lt;/strong&gt; with your document when it updates. A blog, on which you’ve posted a comment, might periodically check whether the information it retreived from your SINP document has changed. This can be done cheaply with negotiation and versioning.&lt;/p&gt;
&lt;p&gt;SINP is easy to implement, it is quite &lt;strong&gt;simple&lt;/strong&gt;. It also is &lt;strong&gt;portable&lt;/strong&gt;, it uses widely supported technologies like XML and HTTP(S) as its base.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SINP is under development&lt;/strong&gt;, but you can already (and really should) take a look to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cvs.codeyard.net/svn/webid/Documentation/"&gt;The latest specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;An &lt;a href="https://cvs.codeyard.net/svn/webid/servers/php/trunk/"&gt;almost complete SINP Server implementation in PHP&lt;/a&gt;. Notice that it’s a subversion repository.&lt;/li&gt;
&lt;li&gt;A proof of concept &lt;a href="https://cvs.codeyard.net/svn/webid/clientlibs/php/clientsinplib.php"&gt;SINP client written in PHP&lt;/a&gt;. (subversion over http!)&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://w-nz.com/sinp"&gt;w-nz.com SINP server&lt;/a&gt;, you can &lt;strong&gt;register your own SINP identity, now&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;&lt;a href="http://w-nz.com/sinpblog"&gt;A hacked wordpress blog&lt;/a&gt; to allow you to post comments with your SINP address, as a proof of concept.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://codeyard.net/"&gt;The kind people who hosted the project&lt;/a&gt; and who even awarded us a price for the project :-).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SINP is based on things I’ve seen floating around on the web, for instance &lt;a href="http://www.zefhemel.com/archives/2005/08/13/sptp-decentralized-single-sign-on"&gt;Zef`s SPTP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At the moment of writing we’re developing a PHP client, a Python client and continueing development of the PHP server. You’re welcome to participate!&lt;/p&gt;
&lt;p&gt;We hope you like it, comments or any other forms of participation would be very welcome.&lt;/p&gt;
&lt;p&gt;Bas, Bram and Noud.&lt;/p&gt;</description></item><item><title>SINP & Codeyard</title><link>https://blog.affien.com/archives/2006/07/01/sinp-codeyard/</link><pubDate>Sat, 01 Jul 2006 00:58:38 +0100</pubDate><guid>https://blog.affien.com/archives/2006/07/01/sinp-codeyard/</guid><description>&lt;p&gt;SINP, a protocol that provides you with an identity that allows authentication and negotation of information linked with the identity as an identity document (basically the whole functionality put into a way too short sentence), which was deviced by Noud, Bram and me, has won the &lt;a href="http://www.codeyard.net/documenten/CapgeminiPrijs.php"&gt;Capgemini Opensource Award&lt;/a&gt;! Lots of rejoice! You will hear more about this :-).&lt;/p&gt;</description></item><item><title>On IE7</title><link>https://blog.affien.com/archives/2006/06/26/on-ie7/</link><pubDate>Mon, 26 Jun 2006 19:48:33 +0100</pubDate><guid>https://blog.affien.com/archives/2006/06/26/on-ie7/</guid><description>&lt;p&gt;I’ve had to test some website I designed on IE (VMWare offcourse) and it went really bad. IE 6 sucks, that’s for sure. It was a blow in the face for me, because everything went so terribly smoothly, escpecially the CSS.&lt;/p&gt;
&lt;p&gt;I was wondering whether it would be as bad in IE 7 as in 6, so I installed it (Genuine Advantage doesn’t work by the way).&lt;/p&gt;
&lt;p&gt;I was amazed by the amount of improvement they made.&lt;/p&gt;
&lt;p&gt;The website was a mess in IE6: backgrounds wouldn’t show up; no attribute selectors on CSS; blocks were positioned in absolute ridiculous locations. Whereas in IE7 it showed up pretty nicely compared to 6. It wasn’t perfect though, there were quite a few glitches in positioning (go IE box model!) and font sizes, but that’s managable.&lt;/p&gt;
&lt;p&gt;I wonder whether IE7 took so long and why it still isn’t as bug-less and feature-complete as almost every other big browser. If microsoft wanted to make a perfect browser, they could do it easily! They’ve got more than enough very talented people and even more than enough money to hire/bribe any expert they’d want.&lt;/p&gt;
&lt;p&gt;Maybe they’re afraid of big AJAX applications. I bet gmail took a pretty big market share of outlook. At least, that is what other people are thinking. They may be right, but google wasn’t stopped by the bugs in IE, google doesn’t use nice and semantically correct HTML (and it is the correct stuff that usually doesn’t work on IE), they just use the stuff that works anyway.&lt;/p&gt;
&lt;p&gt;More likely they don’t care. They force website devs already to create sites that show up properly in IE, just because of its market share. Only website creators feel the pain of the buggy IE engine, not the users of the browser. Besides that it could be a pain for them to create a whole new IE, which needs to be backwards compatible with the old IE. A lot of people would be angry if their site doesn’t show up properly anymore in the new IE — and these people can’t be persuaded with the nice semantics ideology.&lt;/p&gt;
&lt;p&gt;A little bit more pressure by alternative browsers could force microsoft to release something more profound than IE7. Although IE7 is an improvement, they could have done better.&lt;/p&gt;</description></item><item><title>DDOS on Hash Tables (Self Balancing Hash Tables)</title><link>https://blog.affien.com/archives/2006/06/25/ddos-on-hash-tables-self-balancing-hash-tables/</link><pubDate>Sun, 25 Jun 2006 17:08:01 +0100</pubDate><guid>https://blog.affien.com/archives/2006/06/25/ddos-on-hash-tables-self-balancing-hash-tables/</guid><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Hash_table"&gt;Hash Tables&lt;/a&gt; are widely used in server software. A malicious user can easily forge keys in the communication with the server that will result in hashes from the keys so that they will end up in the same bucket. This will force the hashtable to grow each time this bucket is filled.&lt;/p&gt;
&lt;p&gt;In a worst case implementation, this will result in an enormous amount of empty buckets and only one full bucket. Even if the implementation is smart and will therefore only will grow the targetted bucket, the hash table will fail its use. The hash table is meant to make lookups for a key fast by distributing the pairs in buckets, this effect is gone when all pairs are located in one bucket, which will cause linear time look-ups.&lt;/p&gt;
&lt;p&gt;One malicious user won’t be able to crash a server, but a DDOS attack with several users would be tremendously more efficient when targeting this weakness in hash tables.&lt;/p&gt;
&lt;p&gt;A simple solution would be to randomly pick a salt for the hash function on each new instance of a hash table. Basically we prefix each key with a random salt before we hash it. The malicious user might know the hash function, but he has to guess the salt, which neglects the effect.&lt;/p&gt;
&lt;p&gt;Additionally logic could be added to detect an unbalanced hash table and switch the salt on when the table is unbalanced.&lt;/p&gt;
&lt;p&gt;This could also be usefull to balance hash tables when there is no malicious user, but the keys are possibly unfortunate.&lt;/p&gt;</description></item><item><title>Gentoo and BC4000 series RAID cards</title><link>https://blog.affien.com/archives/2006/06/08/gentoo-and-bc4000-series-raid-cards/</link><pubDate>Thu, 08 Jun 2006 20:54:52 +0100</pubDate><guid>https://blog.affien.com/archives/2006/06/08/gentoo-and-bc4000-series-raid-cards/</guid><description>&lt;p&gt;Raidcore hasn’t released drivers that support gentoo linux, only precompiled drivers for the other big distro’s.&lt;/p&gt;
&lt;p&gt;I’ve managed to get the drivers for the bc4000 series to work on Gentoo Linux 2006.0 on linux-2.6.16-gentoo-r9 for the &lt;a href="http://www.broadcom.com/products/Enterprise-Small-Office/Storage-Solutions/BC4852"&gt;bc4852&lt;/a&gt; card.&lt;/p&gt;
&lt;p&gt;You need the &lt;a href="http://www.broadcom.com/support/license.php?file=LIN-DRV-SDK_RC-210-2006044_3.tar"&gt;driver SDK&lt;/a&gt;, which contains the source of the precompiled drivers they distribute.&lt;/p&gt;
&lt;p&gt;I had to tweak some kernel configurations to get it to work — first of I had to turn the ‘sysrq magic key’, although it seems easy to remove all sysrq usage in the drivers itself iif you aren’t comfortable with sysrq.&lt;/p&gt;
&lt;p&gt;I had to switch from ‘discontiguous memory’ to ‘sparse memory’ layout — the driver relies on the availability of ‘mem_map’.&lt;/p&gt;
&lt;p&gt;In the Makefile of the bcraid there’s an issue with the PLATFORM define. It should be defines with ‘uname -m’ instead — otherwise it won’t link in the binary blob.&lt;/p&gt;
&lt;p&gt;The bccfg init script they provide seems terribly useless, adding ‘bccfg’, and ‘bcraid’ for that matter, to /etc/modules.autoload.d/kernel-2.6 does just as fine, but cleaner.&lt;/p&gt;
&lt;p&gt;Initially it seems that everything works fine, although I’m a bit worried about a lot of errors related to the bccfg device nodes in dmesg.&lt;/p&gt;</description></item><item><title>Downtime 1st June</title><link>https://blog.affien.com/archives/2006/05/27/downtime-1st-june/</link><pubDate>Sat, 27 May 2006 19:57:57 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/27/downtime-1st-june/</guid><description>&lt;p&gt;The vserver will be upgraded the first of June. There will be some downtime while copying the FS to a larger partition.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: The server has been upgraded. A little bit later though than expected.&lt;/p&gt;</description></item><item><title>GMail inbox size plotted</title><link>https://blog.affien.com/archives/2006/05/27/gmail-inbox-size-plotted/</link><pubDate>Sat, 27 May 2006 15:38:57 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/27/gmail-inbox-size-plotted/</guid><description>&lt;p&gt;&lt;a href="http://www.googlified.com"&gt;Haochi&lt;/a&gt; has &lt;a href="http://www.googlified.com/2006gmail-storage-space-plotted"&gt;plotted the inbox size of gmail over time&lt;/a&gt;, interesting.&lt;/p&gt;</description></item><item><title>e</title><link>https://blog.affien.com/archives/2006/05/25/e/</link><pubDate>Thu, 25 May 2006 22:39:27 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/25/e/</guid><description>&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mstyle scriptlevel="0" displaystyle="true"&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;munder&gt;&lt;mrow&gt;&lt;mi&gt;lim&lt;/mi&gt;&lt;mo&gt;⁡&lt;/mo&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi mathvariant="normal"&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/munder&gt;&lt;msup&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msup&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\displaystyle e=\lim_{n\to\infty} \left(1+\frac{1}{n}\right)^n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;Yay, it seems &lt;a href="http://www.sixthform.info/steve/wordpress/"&gt;the wordpress &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mtext&gt;TeX&lt;/mtext&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\TeX&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; plugin&lt;/a&gt; works.&lt;/p&gt;</description></item><item><title>sudo is evil</title><link>https://blog.affien.com/archives/2006/05/25/sudo-is-evil/</link><pubDate>Thu, 25 May 2006 20:55:35 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/25/sudo-is-evil/</guid><description>&lt;p&gt;&lt;code&gt;sudo&lt;/code&gt;, the *nix tool with which you can easily execute commands as a super user is harmful.&lt;/p&gt;
&lt;p&gt;The idea behind &lt;code&gt;sudo&lt;/code&gt; is good. You are able to execute super user commands — offcourse when the super user has allowed you — without having to log into the super user.&lt;/p&gt;
&lt;p&gt;The problem though is that the default configuration of sudo only asks for the password of the current user, when he first uses it. That means that if the security is breached of the user, which could happen, it can simply use &lt;code&gt;sudo&lt;/code&gt; to gain access to root, for it is very likely that users who have enabled &lt;code&gt;sudo&lt;/code&gt;, use it a lot.&lt;/p&gt;
&lt;p&gt;My recommendation: &lt;em&gt;don’t use &lt;code&gt;sudo&lt;/code&gt;, if you haven’t explicitly configured it to require your password every single time you use it&lt;/em&gt; — use &lt;code&gt;su&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;update&lt;/strong&gt;: If you want to force &lt;code&gt;sudo&lt;/code&gt; to ask your password every time you use it, add this in your &lt;code&gt;/etc/sudoers&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Defaults timestamp_timeout=0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;They could’ve used a more sensible name for that in my opinion. I had to read the manual carefully before I found out it was this entry.&lt;/p&gt;</description></item><item><title>Keep your email secure (and what just doesn’t work)</title><link>https://blog.affien.com/archives/2006/05/21/keep-your-email-secure-and-what-just-doesnt-work/</link><pubDate>Sun, 21 May 2006 00:15:26 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/21/keep-your-email-secure-and-what-just-doesnt-work/</guid><description>&lt;p&gt;The best way to keep your e-mail address secure from evil spam bots is some kind of javascript and obfuscation, which unfortunately isn’t always available. There are enough alternatives though.&lt;/p&gt;
&lt;p&gt;Usually people tend to replace the ‘@’ with some short replacement like ‘{at}’ or ‘bij’. This just doesn’t help.&lt;/p&gt;
&lt;p&gt;Any programmer with a bit of knowledge of regex can create a program that scans for domain names and interprets every small bit of text in front of it as an @ sign.&lt;/p&gt;
&lt;p&gt;Some smarter people also replace the dot. This works, unless your email-host uses a easily recognizable TLD (.com) or domainname (gmail.com).&lt;/p&gt;
&lt;p&gt;Also putting ‘SPAM’ in your email-adress some.personREMOVETHISFORSPAM@foo.bar is easily filtered.&lt;/p&gt;
&lt;p&gt;Best thing is to use something out of the box.&lt;/p&gt;
&lt;p&gt;For instance, my email address is X@Y, where:&lt;br&gt;
X = bas.westerbaan&lt;br&gt;
Y = gmail.com&lt;br&gt;
Also I’ve got an email-address on w-nz.com, namely bas.westerbaan.&lt;/p&gt;
&lt;p&gt;Or even maybe w-nz.com@bas.&lt;/p&gt;</description></item><item><title>Anonymous comments disabled re-enabled</title><link>https://blog.affien.com/archives/2006/05/19/anonymous-comments-disabled/</link><pubDate>Fri, 19 May 2006 22:09:49 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/19/anonymous-comments-disabled/</guid><description>&lt;p&gt;I’ve disabled anonymous comments for my blog, because my blog is spammed with ~100 spam-comments a day — it seems they’ve worked around &lt;a href="http://elliottback.com/wp/archives/2005/10/23/wordpress-hashcash-30-beta/"&gt;Hashcash 3.0&lt;/a&gt;. I’ll look into this a bit more when I’ve got time. Sorry for the inconvenience.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; Seems it were nasty trackbacks instead of comments. So I just disabled trackbacks. You can comment again.&lt;/p&gt;</description></item><item><title>First SINP draft</title><link>https://blog.affien.com/archives/2006/05/16/first-sinp-draft/</link><pubDate>Tue, 16 May 2006 08:21:49 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/16/first-sinp-draft/</guid><description>&lt;p&gt;SINP is a set of protocols to transfer a profile/identity; to authenticate owners of identities and negotiate for restricted information in protocols. It’s designed to be simple, being based on HTTPS and XML.&lt;/p&gt;
&lt;p&gt;You can find the &lt;a href="http://w-nz.com/~darkshines/SINP.pdf"&gt;first draft here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Subversion repository: https://cvs.codeyard.net/svn/webid&lt;/p&gt;
&lt;p&gt;Acknoledgements: it’s loosely based on other stuff that has been floating around the web, like &lt;a href="http://www.zefhemel.com/archives/2005/08/13/sptp-decentralized-single-sign-on"&gt;Zef’s SPTP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comments would be appreciated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Photo’s are in of the presentation we’ve given about SINP last wednesday:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeyard.net/fotos/capaward-1.php"&gt;http://www.codeyard.net/fotos/capaward-1.php&lt;/a&gt;&lt;br&gt;
Our presentation has got several penguin mascottes.&lt;/p&gt;</description></item><item><title>GMail`s strange perception of EMail size</title><link>https://blog.affien.com/archives/2006/05/02/gmails-strange-perception-of-email-size/</link><pubDate>Tue, 02 May 2006 00:44:26 +0100</pubDate><guid>https://blog.affien.com/archives/2006/05/02/gmails-strange-perception-of-email-size/</guid><description>&lt;p&gt;I’ve just downloaded my whole GMail account via POP3. Each message is stored as-is, including headers and attachments in base64, in a seperate file.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;du -ms&lt;/em&gt; on the folder with all emails tells me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2117&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While &lt;em&gt;GMail&lt;/em&gt; tells me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You are currently using 2079 MB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why this difference, I asked myself. Was there a difference in the way e-mail was stored? Actually I stored my e-mail very inefficiently. E-Mail is 7bits encoded — every character is 7 bits — where my FS (like virtually every other) stores each character in a 8bits. Lets calculate the actual size of email on my disk:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;gt;&amp;gt;&amp;gt; 2117 / 8 * 7&lt;br&gt;
1848&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It gets even more absurd considering that the most part of that space is used by attachments in emails, which are encoded in Base64, which uses 6bits per character. At least 50% of these 2GB are attachments, thus:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;gt;&amp;gt;&amp;gt; 2117 / 8 * 6.5&lt;br&gt;
1716&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why am I using 2079MB according to GMail?&lt;/p&gt;
&lt;p&gt;GMail wouldn’t require 2079MB for my emails, they probably compress all attachments and old mails, they won’t even come near that 2079MB. It would therefore seem logical that they would use the &lt;em&gt;real&lt;/em&gt; size of all emails — which should at least match the 1848MB or 2117MB, but it doesn’t.&lt;/p&gt;
&lt;p&gt;Anyone got a good guess?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This isn’t in any way meant to be anti-gmail — I love gmail, everyone loves gmail! I’m just curious.&lt;/p&gt;</description></item><item><title>Last.fm</title><link>https://blog.affien.com/archives/2006/04/13/lastfm/</link><pubDate>Thu, 13 Apr 2006 20:08:40 +0100</pubDate><guid>https://blog.affien.com/archives/2006/04/13/lastfm/</guid><description>&lt;p&gt;&lt;a href="http://last.fm/"&gt;last.fm&lt;/a&gt; is a (omfg! web2.0) service that tracks the music you play. You just install a plugin for your favourite music player and all songs you play will be send to the site. They will create nice charts, make recommendations and lots of other fun stuff.&lt;/p&gt;
&lt;p&gt;Oh look, it even has got syndication! (my recently played tracks)&lt;br&gt;
&lt;a href="http://www.last.fm/user/baswesterbaan/?chartstyle=asimpleblue5"&gt;&lt;img src="http://imagegen.last.fm/asimpleblue5/recenttracks/baswesterbaan.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see nice charts about my music &lt;a href="http://www.last.fm/user/baswesterbaan/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>SQL on rails</title><link>https://blog.affien.com/archives/2006/04/01/sql-on-rails/</link><pubDate>Sat, 01 Apr 2006 19:50:00 +0100</pubDate><guid>https://blog.affien.com/archives/2006/04/01/sql-on-rails/</guid><description>&lt;p&gt;You’ve got to love the web2.0 impact on aprilfools:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www2.sqlonrails.org"&gt;A search engine in a few lines of code with SQL on rails.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The .tgz you can download is (deliberately) corrupted. You can still recover some amusing stuff from it. Give it a try.&lt;/p&gt;</description></item><item><title>IThreads</title><link>https://blog.affien.com/archives/2006/03/22/ithreads/</link><pubDate>Wed, 22 Mar 2006 11:22:54 +0100</pubDate><guid>https://blog.affien.com/archives/2006/03/22/ithreads/</guid><description>&lt;p&gt;While working on paradox, Kaja and I felt that we needed a cross-platform threading library, which handles all the subtle differences in capabilities and semantics of each platform`s API.&lt;/p&gt;
&lt;p&gt;After a rewrite of Kaja`s original code, I present to you ithreads. You can find the source in this &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;svn://w-nz.com/px&lt;/p&gt;
&lt;p&gt;At this moment ithreads gives you implementations of:&lt;/p&gt;
&lt;p&gt;Mutex&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Event (aka. conditional variable)&lt;/li&gt;
&lt;li&gt;Semaphore&lt;/li&gt;
&lt;li&gt;R/w lock&lt;/li&gt;
&lt;li&gt;Barrier&lt;/li&gt;
&lt;li&gt;Gate&lt;/li&gt;
&lt;li&gt;Thread&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By using (one or more of) the following APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pthreads, posix thread API (unix, linux …)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.gnu.org/software/pth/"&gt;pth&lt;/a&gt;, portable user-space threads&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ds9a.nl/futex-manpages/futex4.html"&gt;futex&lt;/a&gt;, linux`s lightweight fast hybrid locking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ithreads will use generic implementations in case one of the primitives (eg. Semaphore for pthreads) isn’t available on your system.&lt;/p&gt;
&lt;p&gt;I’m espacially happy with the futex based implementations. They outperform the pthreads implementation, and are a lot smaller (4 vs. ~16 bytes for a mutex in pthreads) – although they aren’t as robust (but still correct).&lt;br&gt;
Support for BeOS, OS/2, Windows and more will be added, but testing them will be tricky.&lt;/p&gt;
&lt;p&gt;The library will still need a lot of stress testing and probably still contains some bugs – you’re warned. When everything works nicely I’ll add all kinds of extra flavours of the primitives, eg. read-favouring r/w-lock.&lt;/p&gt;
&lt;p&gt;I hope it will prove useful.&lt;/p&gt;</description></item><item><title>Thread synchronization mechanisms (Locks)</title><link>https://blog.affien.com/archives/2006/03/02/locks/</link><pubDate>Thu, 02 Mar 2006 00:02:55 +0100</pubDate><guid>https://blog.affien.com/archives/2006/03/02/locks/</guid><description>&lt;p&gt;To share it with you and making sure I won’t forget, I present you with (some of) the different thread synchronization mechanisms known to mankind. Most of the mechanisms are used to lock operations or data, some aren’t. You know, those nifty little things that ought to help you with thread hell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Semaphore&lt;/strong&gt;&lt;br&gt;
The semaphore is the cournerstone of locking – often other locks are implemented using one or more semaphores. A semaphore is a simple integer. The initial value of this integer is the amount of threads that can attain (aka. lock, down, enter, pass …) the semaphore before it will block incoming threads – a blocked thread will have to wait until a thread that has attained the semaphore releases (aka. unlocks, ups, leaves …) the semaphore.&lt;/p&gt;
&lt;p&gt;The implementation of a semaphore is an atomic integer on most systems. When a thread wants to attain the semaphore it will check whether the value is greater than 0. If it is it will decrement the value and the semaphore has been attained. If the value is 0 it means that there are already as much threads that have attained the lock as the semaphore allows – and the thread will wait a while and try again. If a thread releases the semaphore it will increment the value.&lt;/p&gt;
&lt;p&gt;You can compare a semaphore with a dining table in a mess hall at which only a certain amount of people can dine. People will either have to wait for someone to finish and stand up, or they’ll have to look for some other place.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mutex&lt;/strong&gt;&lt;br&gt;
The &lt;strong&gt;mut&lt;/strong&gt;ual &lt;strong&gt;ex&lt;/strong&gt;clusion lock is the lock you’ll be most familiar with and is often just referred to as a lock, because of its popularity. A mutex is either locked or unlocked. Only one thread can hold the lock – all others will have to wait for that other thread to release the mutex. The mutex is often used to assure mutual exclusive access to a certain operation or piece of data.&lt;/p&gt;
&lt;p&gt;A mutex is simply just implemented as a semphore with a starting value of 1. The first thread that would attain the mutex would decrement the value to 0 and block all other incoming threads – until it releases the lock.&lt;/p&gt;
&lt;p&gt;You can compare a mutex with the door lock on your restroom, it will help you make sure that you got some privacy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Event&lt;/strong&gt;&lt;br&gt;
An event will block all incoming threads, until it is signalled to release a thread or all of them at the same time. Events are quite useful when dealing with situations when you want to queue threads before they are allowed to pass. Events aren’t locks that you lock and after that have to unlock. A thread just waits for an event, and doesn’t have to ‘unlock’ it afterwards.&lt;/p&gt;
&lt;p&gt;An event is usually also implemented using a semaphore. This time the default value of the semaphore would be 0. If a thread wants to pass the event it’ll try to decrement the semaphore`s value, unless it is 0 in which case it’ll wait, just as you would normally lock a semaphore. If the event is signalled to release a thread it will increment the semaphore`s value – one of the waiting threads will notice that the value isn’t 0 anymore, decrement it to 0 again and pass. If the event is signalled to release all waiting threads it’ll keep on incrementing the value until all threads have passed. Usually there is a mutex alongside the semaphore to make sure that a thread can’t slip in, while all threads are being released, and be released to soon.&lt;/p&gt;
&lt;p&gt;You can compare an event with a (chaotic) queue in front of a fun park attraction. People have to wait until the operator of the attraction tells one of them to continue, or tells all of them to continue at once. (the attraction could be nearly empty with enough room for all of them).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gate&lt;/strong&gt;&lt;br&gt;
A gate is a flavour of an event. It blocks incoming threads just like an event, and lets all of them through if signalled. The difference it that it won’t close again – once signalled (‘opened’) it’ll allow all threads through until it is explicitly closed. It also can’t let threads through one by one.&lt;/p&gt;
&lt;p&gt;A gate is usually implemented using a semaphore, with the initial value of 0 so it will block incoming threads. Each incoming thread tries to attain the semaphore as is done too with the event – but when a semaphore lock is attained it’ll directly release the semaphore so it’ll be available for another thread waiting to pass too.&lt;/p&gt;
&lt;p&gt;You can compare a gate with a … gate. Or a draw bridge if you like. If it’s closed none can pass. If it’s opened everyone can pass. Very straightforward.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Barrier&lt;/strong&gt;&lt;br&gt;
A barrier blocks all incoming thread until there are a certain number of threads. In that case the barrier will release all those threads, but will remain to block incoming threads (until they have reached the specified count together too, etc). A barrier is useful to make sure that a set of threads all start something at the same time and maybe even more important aren’t doing what they did before.&lt;/p&gt;
&lt;p&gt;A barrier is usually implemented as a custom event, that will have a waiter-count-field (and a mutex to synchronize access to it), which will auto release all threads when the waiter count has reached the specified number.&lt;/p&gt;
&lt;p&gt;You can compare a barrier with watter drops from a tap. The drop won’t fall until there is a specific amount of water that causes it to fall.&lt;/p&gt;
&lt;p&gt;So far for the thread synchronization mechanisms today. Tomorrow I’ll maybe talk about the hassles of implementing them yourself.&lt;/p&gt;
&lt;p&gt;Some credit goes to Kaja, who told me about all these locks in the first place :-).&lt;/p&gt;</description></item><item><title>Upgraded to WordPress 2.0.1</title><link>https://blog.affien.com/archives/2006/03/01/upgraded-to-wordpress-201/</link><pubDate>Wed, 01 Mar 2006 18:41:16 +0100</pubDate><guid>https://blog.affien.com/archives/2006/03/01/upgraded-to-wordpress-201/</guid><description>&lt;p&gt;Just upgraded to &lt;a href="http://wordpress.org/development/2006/01/201-release/"&gt;WordPress 2.0.1&lt;/a&gt;, which was way too easy:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;# in my blog.w-nz.com htdocs folder&lt;br/&gt;
wget http://wordpress.org/latest.tar.gz&lt;br/&gt;
tar -xvzpf latest.tar.gz&lt;br/&gt;
cp wordpress/* . -R&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Visit the upgrade script, which consisted out of one simple click and I was done.&lt;/p&gt;
&lt;p&gt;Great stuff.&lt;/p&gt;
&lt;p&gt;PS. I reuploaded my logo and google analytics code too, but they don’t count, really (even though they consisted out of more work that the rest of the upgrade).&lt;/p&gt;</description></item><item><title>Gentoo linux 2006.0 installer</title><link>https://blog.affien.com/archives/2006/02/28/gentoo-linux-20060-installer/</link><pubDate>Tue, 28 Feb 2006 10:36:40 +0100</pubDate><guid>https://blog.affien.com/archives/2006/02/28/gentoo-linux-20060-installer/</guid><description>&lt;p&gt;Today &lt;a href="http://gentoo.org/"&gt;Gentoo&lt;/a&gt; released a live-cd with a gentoo-installer on it. They also posted some &lt;a href="http://shots.osdir.com/slideshows/slideshow.php?release=588&amp;amp;slide=7"&gt;nice screenshots&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Gentoo Linux is a linux redistribution that features its home-made package manager Portage. This package manager makes Gentoo special. There are a lot of other package managers, but Portage is one of the only package managers that compiles each package on your computer, instead of installing precompiled binary’s.&lt;/p&gt;
&lt;p&gt;Compiling everything yourself has got the advantage that you can tweak your package to your specific needs. This means you can have a nice customized system. But the key advantage is performance. Most binaries that package managers install are compiled for generic x86. That means that it can even run on your old 486. The issue is that a lot has changed since the 486. A few new instruction sets (MMX, SSE, etc), specifically designed to increase performance for common tasks, are present in almost every processor which aren’t used by generic x86 compiled binaries. And even more performance advantages&lt;sup&gt;1&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;For this reason some people already did this (see &lt;a href="http://www.linuxfromscratch.org/"&gt;Linux From Scratch&lt;/a&gt;). The problem is that it takes a lot of time to configure, build, install and trouble shoot at least 200 packages. If you take into account that your average server and desktop have at least 15 updated packages per week you are looking at a huge amount of dedication and time required to keep your own Linux From Scratch up to date.&lt;/p&gt;
&lt;p&gt;This is where Gentoo and Portage comes in. If you want apache, you simply type &lt;code&gt;emerge apache&lt;/code&gt;. If you want to update everything, you simply type &lt;code&gt;emerge -u world&lt;/code&gt;. Portage checks which packages are required, it downloads them, it patches them, compiles them and installs them for you.&lt;/p&gt;
&lt;p&gt;But wait? Maybe I don’t want &lt;em&gt;ssl&lt;/em&gt; build into apache. How do I do that? Fairly simple actually. Portage has got a system called &lt;strong&gt;use-flags&lt;/strong&gt;. There is a useflag called &lt;code&gt;ssl&lt;/code&gt;. You can put &lt;code&gt;~ssl&lt;/code&gt; in the &lt;code&gt;USE&lt;/code&gt; entry in &lt;code&gt;/etc/make.conf&lt;/code&gt; to tell to portage that you don’t want ssl on any package. Or you could put &lt;code&gt;net-www/apache ~ssl&lt;/code&gt; in &lt;code&gt;/etc/portage/package.use&lt;/code&gt;, which tells that you want ssl to be disabled for apache.&lt;/p&gt;
&lt;p&gt;Off course Portage isn’t perfect, and you will have some trouble once in a while, but it’s better than the headaches caused by LFS and the reward is similar2.&lt;/p&gt;
&lt;p&gt;— A happy Gentoo user.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/strong&gt;When compiling for generic x86 a lot of memory is aligned which causes a lot of overhead for processors that don’t really care a lot about alignment. Not only are there these nice new instruction sets, but each processor has got specific differences in the implementation of the instruction. On some processors instruction X may be faster than instruction Y. Also some processor information in tight loops can be useful. On one processor the loop may fit in L1-cache, on others it wouldn’t.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/strong&gt;You can offcourse do more with LFS. But usually it isn’t that important, and if it were it would be better to add it into Portage yourself than to switch to LFS for that reason.&lt;/p&gt;</description></item><item><title>Xgl</title><link>https://blog.affien.com/archives/2006/02/19/xgl/</link><pubDate>Sun, 19 Feb 2006 20:49:24 +0100</pubDate><guid>https://blog.affien.com/archives/2006/02/19/xgl/</guid><description>&lt;p&gt;After a long night wrestling with alfa source code, I’ve managed to install Xgl.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/02/xgl-teh-pwn3.jpg" title="Xgl ownage"&gt;&lt;img alt="Xgl ownage" decoding="async" height="96" id="image165" loading="lazy" src="http://blog.w-nz.com/wp-content/uploads/2006/02/xgl-teh-pwn3.thumbnail.jpg" width="120"/&gt;&lt;/a&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/02/xgl-teh-pwn5.jpg" title="Xgl transparency"&gt;&lt;img alt="Xgl transparency" decoding="async" height="96" id="image167" loading="lazy" src="http://blog.w-nz.com/wp-content/uploads/2006/02/xgl-teh-pwn5.thumbnail.jpg" width="120"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Xgl is a Xorg-X11 layer that uses openGL to achieve some nice stunning effects.&lt;/p&gt;
&lt;p&gt;One of these is to be able to switch desktops by pressing ‘Ctrl+Alt’ and dragging your &lt;em&gt;desktop-cube&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;There are a lot of other things that I can’t show with screenshots. Take a look at &lt;a href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=2&amp;amp;url=http%3A//www.novell.com/linux/xglrelease/&amp;amp;ei=_Mr4Q6fDKpGUiALp-fGIAw&amp;amp;sig2=JxqTHPBaiNItW2cNvLNXPg"&gt;the Xgl release post&lt;/a&gt;. These things include that all forms behave flexible. If I drag a form it’s like it’s made of rubber instead of concrete. Also every form pops up gently animated. There’s also a &lt;em&gt;mac osX expose&lt;/em&gt;-clone, which is really helpfull.&lt;/p&gt;
&lt;p&gt;If you want to install it yourself then the &lt;a href="http://gentoo-wiki.com/HOWTO_XGL"&gt;gentoo wiki article&lt;/a&gt; and &lt;a href="http://www.hboeck.de/item/282"&gt;hanno’s blog post&lt;/a&gt; should be very helpful.&lt;/p&gt;</description></item><item><title>Virtualization isn’t hardware efficient</title><link>https://blog.affien.com/archives/2006/02/09/virtualization-isnt-hardware-efficient/</link><pubDate>Thu, 09 Feb 2006 11:13:53 +0100</pubDate><guid>https://blog.affien.com/archives/2006/02/09/virtualization-isnt-hardware-efficient/</guid><description>&lt;p&gt;Virtualization is the thing right now. Escpacially because VMWare released VMServer for free.&lt;/p&gt;
&lt;p&gt;I’ve read quite a lot of posts about the pro’s about virtualization, and I`m annoyed by some.&lt;/p&gt;
&lt;p&gt;This for some &lt;strong&gt;claim that virtualization is hardware efficient&lt;/strong&gt;. Quite frankly, it isn’t. It is quite inefficient.&lt;/p&gt;
&lt;p&gt;The thing though is that you don’t use your server optimally usually, and that with virtualization you can more easily get most out of your server, although you could get more from your server if you wouldn’t use virtualization. But that is a lot trickier, virtualization is quite flexible.&lt;/p&gt;
&lt;p&gt;Virtualization &lt;strong&gt;doesn’t make hardware more efficient&lt;/strong&gt;, it &lt;strong&gt;makes you more efficient at allocating resources of your server&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This server, w-nz.com, runs on a virtual server. I can’t affort or would fully use a ful dedicated server, but I can affort and use a virtual server. Efficient. But running all sites on the real server on just one server would be more efficient, but harder to do, espacially related to security.&lt;/p&gt;</description></item><item><title>Virtual locality of reference</title><link>https://blog.affien.com/archives/2006/02/07/virtual-locality-of-reference/</link><pubDate>Tue, 07 Feb 2006 13:38:42 +0100</pubDate><guid>https://blog.affien.com/archives/2006/02/07/virtual-locality-of-reference/</guid><description>&lt;p&gt;Quite a lot of programmers consider the advantages of locality of reference; if they put all the data they work with in about the same space the processor will be able to retreive them more easily, for the processor caches regions of memory in the L&lt;em&gt;x&lt;/em&gt; caches.&lt;/p&gt;
&lt;p&gt;Quite a lot of memory managers even move objects for you in the same place which seem to depend on each other. This doesn’t only decrease fragmentation, for they would be freed in the same timespan, but also increase performance due to locality of reference.&lt;/p&gt;
&lt;p&gt;Although the advantage of locality of reference isn’t as big as most people presume in some situations due to virtual memory.&lt;/p&gt;
&lt;p&gt;The address space a process sees is a virtual address space, it is mapped in place by the OS. This means that 0x1234 can contain an image for one process and a normal integer for another process. This enables two processes to be loaded, virtually, in the same place.&lt;/p&gt;
&lt;p&gt;One implication this has on locality of reference is that a seamingly contiguous piece of memory can in physically be distributed over quite a big span of real physical memory. One part of your list could be at 0x1300, the other at 0x30240.&lt;/p&gt;
&lt;p&gt;If your program wants to enumerate through that list it`ll have to query the RAM for the second part, which it wouldn’t have to if it would be contiguous in the physical memory, for then it would most likely be in complete in the L2 cache.&lt;/p&gt;
&lt;p&gt;The physical memory is mapped page by page into the virtual memory space. Usually pages are 2KB. Each page is always contiguous in physical memory for it can’t be split up by mapping. Therefore locality of reference always works within a page.&lt;/p&gt;
&lt;p&gt;It doesn’t mean that if you are working with more than a page of memory it will be all fragmented. The OS usually does a good job at keeping pages contiguous in physical memory when it is contiguous in virtual memory.&lt;/p&gt;
&lt;p&gt;Although when a computer is under some load and it’ll have to use each bit of memory and swap in and out memory it will likely be a lot more fragmented.&lt;/p&gt;
&lt;p&gt;I don’t want people to be ignorant about the advantage of locality of reference when dealing with more than a page of memory. I want people that trade of literally everything for their holy locality of reference to see that it’s just a nice extra, but that it just doesn’t always work due to fragmentation of the physical memory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Side notes&lt;/strong&gt;&lt;br&gt;
Virtual memory is a bit more complicated than I explained, &lt;a href="http://en.wikipedia.org/wiki/Virtual_memory" title="Wikipedia on virtual memory"&gt;read about it on wikipedia&lt;/a&gt;.&lt;br&gt;
Processors will try to keep virtual memory address space in mind to avoid this issue, although it’s limited.&lt;/p&gt;</description></item><item><title>Mulholland Drive</title><link>https://blog.affien.com/archives/2006/01/31/mulholland-drive/</link><pubDate>Tue, 31 Jan 2006 00:05:58 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/31/mulholland-drive/</guid><description>&lt;p&gt;&lt;a href="http://www.mulhollanddrive.com/"&gt;Mulholland Drive&lt;/a&gt; is a great film. If you haven’t watched it yet, just watch it.&lt;/p&gt;
&lt;p&gt;Those lucky enough to be astounded and puzzled by the film have all came up with their own interpretation of the movie.&lt;/p&gt;
&lt;p&gt;The most common interpretation is that either the first or the last part is a dream of the opposite part. I’d have to disagree with that for both parts are just too bizarre to be real. However, both parts are pseudo-opposite.&lt;/p&gt;
&lt;p&gt;Just take the ‘119’ on the firetruck for instance that hasn’t been mirrored, but still reversed.&lt;/p&gt;
&lt;p&gt;It keeps you thinking in any case.&lt;/p&gt;</description></item><item><title>PHP’s hidden treasures</title><link>https://blog.affien.com/archives/2006/01/30/phps-hidden-treasures/</link><pubDate>Mon, 30 Jan 2006 19:37:39 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/30/phps-hidden-treasures/</guid><description>&lt;p&gt;I’ve &lt;a href="http://blog.w-nz.com/archives/2005/02/21/why-php-sucks-and-i-still-use-it/" title="whinage"&gt;complained a lot&lt;/a&gt; when I worked with PHP about PHP’s terribly inefficient design; I’ve complained about it, just because it was PHP. The things I missed most in PHP, it seems, were actually there all along!&lt;/p&gt;
&lt;p&gt;Behold &lt;a href="http://nl2.php.net/manual/en/ref.shmop.php" title="Shared Memory Functions"&gt;shared memory&lt;/a&gt; and &lt;a href="http://nl2.php.net/manual/en/ref.sem.php" title="Semaphore"&gt;yet more IPC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One reason PHP really sucked was that you need to load small data from and to databases or files if you want to share it between page views. The whole concept of handling a request per page view is ridiculous too, IMO.&lt;/p&gt;
&lt;p&gt;With those two libraries however, PHP pages could be way more efficient.&lt;/p&gt;
&lt;p&gt;I wonder why the big PHP software haven’t used it. Lets hope it isn’t &lt;em&gt;portability&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Beacon with eggs and …</title><link>https://blog.affien.com/archives/2006/01/28/beacon-with-eggs-and/</link><pubDate>Sat, 28 Jan 2006 21:14:47 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/28/beacon-with-eggs-and/</guid><description>&lt;p&gt;Spam, again on this blog.&lt;/p&gt;
&lt;p&gt;It seems those nasty spammers are now using actual people (or an automated browser) to post spam comments, subverting the protection wp-hashcash delivers.&lt;/p&gt;
&lt;p&gt;Luckily it are only about two per day, which is very managable, but still annoying.&lt;/p&gt;
&lt;p&gt;Like DRM and most other copyright protections, SPAM protection is inherently insecure, for the original openess required to allow a not-spammer to use them is, well, too open.&lt;/p&gt;
&lt;p&gt;One interesting thing is that we can fight back now that they are using full javascript VM’s. Matching the spam-ip and letting it execute a rather ‘memory inefficient’ little program would certainly make me smile.&lt;/p&gt;</description></item><item><title>Freelancer hash database</title><link>https://blog.affien.com/archives/2006/01/28/freelancer-hash-database/</link><pubDate>Sat, 28 Jan 2006 21:04:17 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/28/freelancer-hash-database/</guid><description>&lt;p&gt;The game &lt;a href="http://www.microsoft.com/games/freelancer/" title="Freelancer homepage"&gt;Freelancer&lt;/a&gt; uses hashes a lot in its data files, which gives modders a hard time.&lt;/p&gt;
&lt;p&gt;I’ve put a &lt;a href="http://w-nz.com/flhdb" title="Freelancer Hash Database"&gt;database online&lt;/a&gt;, which modders can use to look-up hashes.&lt;/p&gt;</description></item><item><title>mail.w-nz.com</title><link>https://blog.affien.com/archives/2006/01/15/mailw-nzcom/</link><pubDate>Sun, 15 Jan 2006 22:51:28 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/15/mailw-nzcom/</guid><description>&lt;p&gt;I’ve successfully installed &lt;em&gt;vpopmail&lt;/em&gt;, &lt;em&gt;qmail&lt;/em&gt; and &lt;em&gt;courier&lt;/em&gt; today, after some hours of work on this server.&lt;br&gt;
&lt;strong&gt;From now on you can send e-mail again to @w-nz.com adresses&lt;/strong&gt;, which won’t end up in &lt;em&gt;/dev/null&lt;/em&gt;. (like bas.westerbaan@~)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;To the users of the server:&lt;/em&gt; if you want an email-address, mail me.&lt;/p&gt;
&lt;p&gt;While testing my &lt;em&gt;smtp&lt;/em&gt; server whether it would receive incoming email properly I was harshly confirmed by it being spam instead of my test mail entering my mailbox first:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/wp-content/uploads/2006/01/Screenshot.png" title="Hello Spam!"&gt;&lt;img alt="Hello Spam!" decoding="async" height="137" id="image157" loading="lazy" src="http://blog.w-nz.com/wp-content/uploads/2006/01/Screenshot.thumbnail.png" width="170"/&gt;&lt;/a&gt;&lt;br&gt;
It’s pretty funny to see spam junk in an ancient text-mode mailing program.&lt;/p&gt;
&lt;p&gt;If anyone experiences problems with any application not mailing you any verification as it should, please email me. It could very possibly be that the &lt;em&gt;qmail-send&lt;/em&gt; isn’t configured properly to allow unauthorized local mails.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: More good news, the amount of RAM on my virtual server has increased to 120MB! Which means that my server won’t be swapping instead of working all the time anymore.&lt;/p&gt;</description></item><item><title>Crash</title><link>https://blog.affien.com/archives/2006/01/12/crash/</link><pubDate>Thu, 12 Jan 2006 21:41:03 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/12/crash/</guid><description>&lt;p&gt;For unkown reason lighttpd decided to pump out a log file of a few GB’s, which totally filled the last single piece of free memory on my server, resulting in the malfunction of several server daemons crashing the server.&lt;/p&gt;
&lt;p&gt;Anyone has experience with this problem?&lt;/p&gt;</description></item><item><title>Welcome to lighttpd</title><link>https://blog.affien.com/archives/2006/01/04/welcome-to-lighttpd/</link><pubDate>Wed, 04 Jan 2006 14:38:59 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/04/welcome-to-lighttpd/</guid><description>&lt;p&gt;After a long afternoon I’ve got &lt;a href="http://www.lighttpd.net/" title="lighttpd homepage"&gt;lighttpd&lt;/a&gt; to work with my current apache based layout.&lt;/p&gt;
&lt;p&gt;This means I can choose whether to run apache or lighttpd.&lt;/p&gt;
&lt;p&gt;Lighttpd is a webserver, like apache. The key advantage of lighttpd over apache is that lighttpd is very light on your server. It uses a lot less memory, which is very nice espacially when considering that my server only has got ~90mB of memory.&lt;/p&gt;
&lt;p&gt;The drawback of lighttpd is that it is light and doesn’t support as much as apache does.&lt;/p&gt;
&lt;p&gt;It doesn’t do &lt;em&gt;.htaccess&lt;/em&gt; files. Everything needs to be configured in the &lt;em&gt;lighttpd.conf&lt;/em&gt;, which doesn’t support everything, or at least not in the same way as apache does.&lt;/p&gt;
&lt;p&gt;However, &lt;em&gt;lighttpd&lt;/em&gt; is pretty easy to configure when you get the hang of it.&lt;/p&gt;
&lt;p&gt;One particulair pain in the ass is getting old mod_rewrite using .htaccess to work, for instance the one used by wordpress of this blog.&lt;/p&gt;
&lt;p&gt;I’ve added this in my &lt;em&gt;lighttpd.conf&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$HTTP[&amp;quot;host&amp;quot;] =~ &amp;quot;blog.w-nz.com&amp;quot; {&lt;br/&gt;
url.rewrite = ( &amp;quot;^/(page|archives|comments|search|feed)/&amp;quot; =&amp;gt; &amp;quot;/index.php?error=404&amp;quot; )&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;One interesting thing to note is that the configuration file is nothing more than a script being executed for each request.&lt;/p&gt;</description></item><item><title>Welcome to wordpress 2.0</title><link>https://blog.affien.com/archives/2006/01/01/welcome-to-wordpress-20/</link><pubDate>Sun, 01 Jan 2006 17:16:11 +0100</pubDate><guid>https://blog.affien.com/archives/2006/01/01/welcome-to-wordpress-20/</guid><description>&lt;p&gt;I’ve just upgraded my blog to the &lt;a href="http://wordpress.org/development/2005/12/wp2/" title="wordpress 2.0 release post"&gt;new wordpress 2.0&lt;/a&gt;, which seems to work properly.&lt;/p&gt;
&lt;p&gt;Espacially the back-end has got a face lift, which looks and feels really nice.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update: redid the logo and changed the theme to show the author&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;And offcourse: &lt;strong&gt;Happy newyear!&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Rainbow Tables: Coverage</title><link>https://blog.affien.com/archives/2005/12/26/rainbow-tables-coverage/</link><pubDate>Mon, 26 Dec 2005 02:45:52 +0100</pubDate><guid>https://blog.affien.com/archives/2005/12/26/rainbow-tables-coverage/</guid><description>&lt;p&gt;A rainbow table is generated by creating (&lt;em&gt;m&lt;/em&gt;) chains using randomly picked starting keys. The reduction functions result (or ought to result at least) in evenly distributed new keys. Their is only a probability that a certain key/cipher pair is in the table.&lt;/p&gt;
&lt;p&gt;I’ll gradually explain how the coverage can be calculated.&lt;/p&gt;
&lt;p&gt;Take &lt;em&gt;m&lt;/em&gt; chains, each 1 long to cover a keyspace of N keys. The chance that you can find the key is:&lt;/p&gt;
&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mstyle scriptlevel="0" displaystyle="true"&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\displaystyle P = \frac{m}{N}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;When we have 1/2N chains, we’ll subsequently have a P of 1/2, a 50% coverage. Obvious.&lt;/p&gt;
&lt;p&gt;When each chain would be 2 in length it gets trickier.&lt;/p&gt;
&lt;p&gt;&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;P = \frac{m}{N}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; still is the chance that we can find the key in the first column (first item of each chain of the table) of the table. The second column isn’t as straight forward. We’ve blindly assumed that each key in the first column is unique, which is true for the first column, but certainly isn’t for the second column. A few chains can merge. The second column is ‘random’.&lt;/p&gt;
&lt;p&gt;The chance that a certain key is in a specific chain of the second column is &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\frac{1}{N}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;. The chance that a certain key is in the second column is &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msup&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;1 - \left(1 - \frac{1}{N} \right)^m&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; (One minus the chance that there isn’t a certain key in a certain chain multiplied by itself the-amount-of-chains times).&lt;/p&gt;
&lt;p&gt;The amount of keys covered by this column is the chance that a certain key is in the column times the amount of keys: &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msup&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/msup&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;N \left(1 - \left(1 - \frac{1}{N} \right)^m \right)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The chance a certain key is in any of the two columns would be:&lt;/p&gt;
&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mfrac&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo&gt;⋅&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msup&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/msup&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;/mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\left( \frac{m}{N} \right) \cdot N \left(1 - \left(1 - \frac{1}{N} \right)^m \right) \over N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;
&lt;p&gt;The third column’s coverage can be calculated by taking the unique keys in the second column as &lt;cite&gt;m&lt;/cite&gt; was taken for the amount of unique keys for the first column. With each chain &lt;em&gt;t&lt;/em&gt; in length this formula applies:&lt;/p&gt;
&lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="block"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mstyle scriptlevel="0" displaystyle="true"&gt;&lt;msub&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mspace&gt;&lt;/mspace&gt;&lt;msub&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mrow&gt;&lt;mo fence="true"&gt;(&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo fence="true"&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mspace&gt;&lt;/mspace&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;munderover&gt;&lt;mo&gt;∏&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/munderover&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mfrac&gt;&lt;msub&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/msub&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mfrac&gt;&lt;/mstyle&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;\displaystyle m_1=m \\ m_{n+1}=N \left( 1 - \left( 1 - \frac {1}{N} \right) \right) \\ P=1-\prod^m_{i=1}1-\frac{m_i}{N}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;</description></item><item><title>Rainbow Tables: Introduction</title><link>https://blog.affien.com/archives/2005/12/26/rainbow-tables-introduction/</link><pubDate>Mon, 26 Dec 2005 01:52:20 +0100</pubDate><guid>https://blog.affien.com/archives/2005/12/26/rainbow-tables-introduction/</guid><description>&lt;p&gt;A rainbow table is a data structure with which it is possible to retreive the key used to generate a ciphertext with a fixed plaintext. One common application is to reverse (password) hashes; which can be seen as cipher functions who take the message as the key and the ciphertext as the generated hash.&lt;/p&gt;
&lt;p&gt;One important thing to note is that all keys and ciphertext pairs stored in the table have been precomputed during generation of the table. Generating a table that stores 1 miljon md5 password hashes, requires all those passwords to be hashed during precompution.&lt;/p&gt;
&lt;p&gt;I’ve been doing some research about rainbow tables and I think it will be usefull to share some of my experiences.&lt;/p&gt;
&lt;p&gt;But before I can dive into the matter I first got to explain how rainbow tables work. (or you can read &lt;a href="http://lasecwww.epfl.ch/php_code/publications/search.php?ref=Oech03"&gt;the ‘official’ paper about rainbow tables&lt;/a&gt; by &lt;em&gt;Philippe Oechslin&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Precomputing a significant amount of key/ciphertext (password/password hash) pairs is fairly easy. The issue is that &lt;em&gt;a significant&lt;/em&gt; amount is fairly large, 2&lt;sup&gt;37&lt;/sup&gt; for alphanumerical windows password hashes to give a real-life example. Because it isn’t practical to store 2&lt;sup&gt;37&lt;/sup&gt; pairs of key/ciphertext’s (~2TB) on your computer; rainbow tables store chains of key/ciphertext’s pairs, more precisely they store only the starting and ending key of a chain.&lt;/p&gt;
&lt;p&gt;Each chain starts with a key (randomly generated; in our example a password). The next item in the chain is the ciphertext which is calculated by the cipher (in our example the hash for the password). The next item is a key (password) again, which was generated from the ciphertext (hash) by a reduction function. This reduction function can be almost everything, it can be a XOR hash, it can be CRC32, as long as it changes the (larger) cipher text into a new key.&lt;/p&gt;
&lt;p&gt;k&lt;sub&gt;1&lt;/sub&gt; — cipher –&amp;gt; C&lt;sub&gt;1&lt;/sub&gt; — reduction function 1–&amp;gt; k&lt;sub&gt;2&lt;/sub&gt; — cipher –&amp;gt; C&lt;sub&gt;2&lt;/sub&gt; — reduction function 2 –&amp;gt;…&lt;/p&gt;
&lt;p&gt;Each chain has got a fixed length (&lt;em&gt;t&lt;/em&gt;). In the table only the first and the last key are stored (&lt;em&gt;k&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt; and &lt;em&gt;k&lt;sub&gt;t&lt;/sub&gt;&lt;sub&gt;&lt;/sub&gt;&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;To look up a certain ciphertext, the reduction function is applied on the cipher text and all the end-keys of all chains are checked whether they match. If one of them matches you can regenerate the chain from the begin key stored allong the end key of the chain, and you’ll find the key that when applied the reduction and the cipher on will result in your ciphertext (which is the last ciphertext in the chain). When no end key matches, the cipher and reduction functions are applied to generate a new key, and all the end key’s are checked again. If one of the end key’s matches you know that your ciphertext is in the chain in the second-last position. Repeat this &lt;em&gt;t&lt;/em&gt; times for each position in the chain.&lt;/p&gt;
&lt;p&gt;It sounds straight forward, but there are some issues that appear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Loops&lt;/strong&gt;, there are some cases where the reduction function generates a key which when being applied the cipher function will become the first plain text. (K = R(S(K)), where R is the reduction function, and S is the cipher). This will cause a the rest of the chain to be useless.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merging chains/False alarms&lt;/strong&gt;, because the ciphertext is larger than the key there will likely be a lot of chains with the same end point, this reduces the total coverage of the table and will cause a lot of additional time spent on the ‘false alarms’ caused by the fact that you have to check each matching endpoint, even if the starting key is the wrong branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To avoid loops; avoid merging chains a bit more and to increase lookup speed, rainbow tables use rainbow chains: each column in the table uses a different reduction function.&lt;/p&gt;
&lt;p&gt;Because we use a different reduction function for each ciphertext in the chain there can’t be loops, or at least not loops that cause redundant data, because a certain ciphertext will become a different key in a different column of the chain.&lt;/p&gt;
&lt;p&gt;The amount of merging chains is also cut by &lt;em&gt;t&lt;/em&gt; times, because a certain key in a chain will only lead to the same chain when it is in the same place of the chain.&lt;/p&gt;
&lt;p&gt;This is a very superficial explanation, read more (when you’re interested) in the &lt;a href="http://lasecwww.epfl.ch/php_code/publications/search.php?ref=Oech03"&gt;original paper&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Merry Christmas</title><link>https://blog.affien.com/archives/2005/12/25/merry-christmas/</link><pubDate>Sun, 25 Dec 2005 11:07:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/12/25/merry-christmas/</guid><description>&lt;p&gt;Merry Christmas!&lt;/p&gt;</description></item><item><title>Christmas carol</title><link>https://blog.affien.com/archives/2005/12/24/christmas-carol/</link><pubDate>Sat, 24 Dec 2005 15:07:26 +0100</pubDate><guid>https://blog.affien.com/archives/2005/12/24/christmas-carol/</guid><description>&lt;p&gt;What would you do when you need to perform something ‘nice’ on a christmas celebration of your high school?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/~darkshines/music/christmassong-0.3.mp3"&gt;This&lt;/a&gt; is what my brother and Noud did.&lt;/p&gt;
&lt;p&gt;Hopefully I`ll be able to grab some photo’s soon and upload them of the stunned faces of the suprised people there.&lt;/p&gt;</description></item><item><title>The problem with rainbow tables</title><link>https://blog.affien.com/archives/2005/12/07/the-problem-with-rainbow-tables/</link><pubDate>Wed, 07 Dec 2005 23:13:47 +0100</pubDate><guid>https://blog.affien.com/archives/2005/12/07/the-problem-with-rainbow-tables/</guid><description>&lt;p&gt;Rainbow tables (&lt;a href="http://lasecwww.epfl.ch/php_code/publications/search.php?ref=Oech03"&gt;Making a Faster Cryptanalytic Time-Memory Trade-Off&lt;/a&gt;) work fairly well, although – because they use different regression functions in the chains – they contain a lot of redundant data.&lt;/p&gt;
&lt;p&gt;The example table in the paper (lanmanager hash; 8 char. alpha; 4666×38223872) contains a lot of redundant data, which can be calculated:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; CalcRedundancy(4666, 38223872, CalcN(26, 1, 7))&lt;br/&gt;
21.50866258033486&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The 300mb table would be stored in a 20mb table if the regression function was to be perfect.&lt;/p&gt;
&lt;p&gt;The problem is that to make a regression function perfect, it should be ‘in paralel’ with the cipher function, which isn’t an option for most of these are engineered to prevent this.&lt;/p&gt;
&lt;p&gt;Adding variable length chains back into the rainbow chains could allow exploiting existing chains more efficiently.&lt;/p&gt;
&lt;p&gt;This probably sounds messy and to be honoust this idea is still a bit messy.&lt;/p&gt;
&lt;p&gt;I`ll write something decent along the way.&lt;/p&gt;</description></item><item><title>Switching to Lighttpd</title><link>https://blog.affien.com/archives/2005/11/22/switching-to-lighttpd/</link><pubDate>Tue, 22 Nov 2005 14:48:08 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/22/switching-to-lighttpd/</guid><description>&lt;p&gt;Recently a lot of people seem to be switching from Apache to &lt;a href="http://www.lighttpd.net/documentation/simple-vhost.html"&gt;Lighttpd&lt;/a&gt;, which is a webserver that is said to be a lot faster, but even better it is said to have a constant low memory footprint.&lt;/p&gt;
&lt;p&gt;I`m currently compiling lighttpd on my vserver (on which this blog runs), and I`ll switch to lighttpd – which should be as easy as setting some configurations for lighttpd to fit in with the current /var/www model I`m using and simply switching off Apache and switching on lighttpd.&lt;/p&gt;
&lt;p&gt;I hope there won’t be a lot downtime.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; Lighttpd and fastcgi don’t seem to really go together on my server configuration, so no lighttpd for a while :(.&lt;/p&gt;</description></item><item><title>Westerbaan Huurman notation</title><link>https://blog.affien.com/archives/2005/11/15/westerbaan-huurman-notation/</link><pubDate>Tue, 15 Nov 2005 00:11:07 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/15/westerbaan-huurman-notation/</guid><description>&lt;p&gt;&lt;code&gt;[C&lt;sub&gt;n&lt;/sub&gt;-H]&lt;sup&gt;1..8&lt;/sup&gt;&lt;br/&gt;
[sigma(n,n+1)]&lt;sup&gt;1..3,5..7&lt;/sup&gt;;&lt;br/&gt;
sigma(4,1);sigma(8,5);&lt;br/&gt;
[sigma(n,n+4)]&lt;sup&gt;1..4&lt;/sup&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;code&gt;C&lt;sub&gt;1&lt;/sub&gt;-5,H-C&lt;sub&gt;2&lt;/sub&gt;-6,H-C&lt;sub&gt;3&lt;/sub&gt;-7,H-C&lt;sub&gt;4&lt;/sub&gt;-8,H,1;&lt;br/&gt;
C&lt;sub&gt;5&lt;/sub&gt;-H-C&lt;sub&gt;6&lt;/sub&gt;-H-C&lt;sub&gt;7&lt;/sub&gt;-C&lt;sub&gt;8&lt;/sub&gt;-H;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[C&lt;sub&gt;n&lt;/sub&gt;-n+4,H]&lt;sup&gt;1..4&lt;/sup&gt;;&lt;br/&gt;
[C&lt;sub&gt;n&lt;/sub&gt;-H]&lt;sup&gt;5..8&lt;/sup&gt;;&lt;br/&gt;
sigma(4,1); sigma(8,5);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;They all represent the same carbon cube. (C&lt;sub&gt;8&lt;/sub&gt;H&lt;sub&gt;8&lt;/sub&gt;)&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Purpose; because the normal naming of chemistry can’t define all structures they come up with trivial names, which I find very annoying. This notation is intended to be able to describe every structure uniformly. And no, don’t even try to pronounce it.&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>Google Analytics</title><link>https://blog.affien.com/archives/2005/11/14/google-analytics/</link><pubDate>Mon, 14 Nov 2005 23:15:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/14/google-analytics/</guid><description>&lt;p&gt;Google’s new service to information domination, &lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt;, it a traffic tracker for your website, originally used with their adwords service, seems pretty nice.&lt;/p&gt;
&lt;p&gt;Well.. if it would be responsive, that is.&lt;/p&gt;
&lt;p&gt;Worse than being slashdotted, a lot of high-traffic bloggers link to it.&lt;/p&gt;
&lt;p&gt;Unintentional Distributed Denail of Service.&lt;/p&gt;</description></item><item><title>Code Golf 3: Googler</title><link>https://blog.affien.com/archives/2005/11/02/code-golf-3-googler/</link><pubDate>Wed, 02 Nov 2005 18:43:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/02/code-golf-3-googler/</guid><description>&lt;p&gt;Code Golf. As with the real sport the goal is to reduce the number of strokes that it takes to complete a particular objective, although with Code Golf â€œstrokesâ€ refers to keystrokes rather than swings of a golf club.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Write code to return the url’s of the first page of search results for the query ‘perl’ on google.com&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There’ll be two categories, one for using perl’s &lt;code&gt;Socket&lt;/code&gt; module only, and for those using external libraries.&lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;</description></item><item><title>Code Golf 2: Line Sort</title><link>https://blog.affien.com/archives/2005/11/01/code-golf-2-line-sort/</link><pubDate>Tue, 01 Nov 2005 21:44:04 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/01/code-golf-2-line-sort/</guid><description>&lt;p&gt;Code Golf. As with the real sport the goal is to reduce the number of strokes that it takes to complete a particular objective, although with Code Golf â€œstrokesâ€ refers to keystrokes rather than swings of a golf club.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create an algorithm that reads lines from the &lt;em&gt;stdin&lt;/em&gt; until it hits an &lt;em&gt;EOF&lt;/em&gt; and prints those lines sorted to the &lt;em&gt;stdout&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t use the language’s native sorting capabilities, write your own sorting algorithm. (&lt;code&gt;print for sort&amp;lt;&amp;gt;&lt;/code&gt; would be too easy.)&lt;/li&gt;
&lt;li&gt;Any language is allowed, except for those that myseriously implement a 1 byte command that does exactly this.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example implementation using inverted bubble sort:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@a = &amp;lt;&amp;gt;;
for ($i = 0; $i &amp;lt;= $#a; $i++) {
 for ($j = $i; $j &amp;lt;= $#a; $j++) {
 if (@a[$i] ge @a[$j]) {
 $t = @a[$j];
 @a[$j] = @a[$i];
 @a[$i] = $t;
 }
 }
}
foreach(@a) {
 print;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This implementation is very large and inefficient, and just an example.&lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;</description></item><item><title>Code Golf 1: Fibonacci</title><link>https://blog.affien.com/archives/2005/11/01/code-golf-1-fibonacci/</link><pubDate>Tue, 01 Nov 2005 19:23:55 +0100</pubDate><guid>https://blog.affien.com/archives/2005/11/01/code-golf-1-fibonacci/</guid><description>&lt;p&gt;Code Golf. As with the real sport the goal is to reduce the number of strokes that it takes to complete a particular objective, although with Code Golf “strokes” refers to keystrokes rather than swings of a golf club.&lt;/p&gt;
&lt;p&gt;You may compete using any language.&lt;sup&gt;1&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create an algorithm that prints the 30 first fibonacci number to the screen, each followed by a newline.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An algorithm which could do this would be (148 bytes):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;my $a = 1;
my $b = 0;
my $c;

my $limit = 30;
my $i = 0;

while ($i &amp;lt; $limit) {
 $i += 1;
 $c = $a + $b;
 $a = $b;
 $b = $c;
 print $c . &amp;#34;\n&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But that can be written way shorter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My first&lt;/strong&gt;: &lt;br&gt;
&lt;br&gt;
&lt;code&gt;$a=1;for((0..29)){$c=$a+$b;$a=$b;$b=$c;print&amp;quot;$c\n&amp;quot;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My second&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;$a=1;$c=$a+$b,$a=$b,$b=$c,print&amp;quot;$c\n&amp;quot;for 0..29&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Noud’s reponse&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;$i=1;print$i+=$a,&amp;quot;\n&amp;quot;,$a+=$i,&amp;quot;\n&amp;quot;while$i&amp;lt;317811&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My revenge&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;$a=1;$c=$a+$b,$a=$b,$b=$c,print&amp;quot;$c\n&amp;quot;for 0..29&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Noud was 30 seconds later with&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;$a=1;print$a+=$b,&amp;quot;\n&amp;quot;,$b+=$a,&amp;quot;\n&amp;quot;for 1..15&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My latest one&lt;/strong&gt;: &lt;ins&gt;partially by Bram too&lt;/ins&gt;&lt;br&gt;
&lt;code&gt;print$a+=$b,&amp;quot;\n&amp;quot;,$b+=$a,&amp;quot;\n&amp;quot;for$a++..14&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update:&lt;/ins&gt;&lt;strong&gt;Twan&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;print$a+=$b,$/,$b+=$a,$/for$a++..14&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;1. a language that implements &lt;code&gt;fib&lt;/code&gt; returning mysteriously the first 30 fibonacci numbers isn’t allowed.&lt;/small&gt;&lt;/p&gt;</description></item><item><title>If only I could cash it</title><link>https://blog.affien.com/archives/2005/10/25/if-only-i-could-cash-it/</link><pubDate>Tue, 25 Oct 2005 08:02:13 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/25/if-only-i-could-cash-it/</guid><description>&lt;p&gt;&lt;img src="http://static.flickr.com/23/25822676_789bf55448_t.jpg" alt=""&gt;&lt;br&gt;
My &lt;a href="http://blog.w-nz.com/"&gt;blog&lt;/a&gt; is worth &lt;strong&gt;$2,258.16&lt;/strong&gt;.&lt;br&gt;
&lt;a href="http://www.business-opportunities.biz/projects/how-much-is-your-blog-worth/"&gt;How much is your blog worth?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.technorati.com/"&gt;&lt;img src="http://technorati.com/pix/tech-logo-embed.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Memory Alignment Havoc</title><link>https://blog.affien.com/archives/2005/10/23/memory-alignment-havoc/</link><pubDate>Sun, 23 Oct 2005 22:50:04 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/23/memory-alignment-havoc/</guid><description>&lt;p&gt;Memory Alignment is one of the most important concepts when working low-level with memory. The bliss of the x86 processor, which is very kind about alignment, has left me unaware of it for years. That was until Kaja mentioned it, and therefore I decided to rebuild my Gc.&lt;/p&gt;
&lt;h3 id="like-err-what-you-talking-bout"&gt;Like err.. what you talking ’bout?&lt;/h3&gt;
&lt;p&gt;Data should be aligned in the memory. Why? Because the processor doesn’t see the memory as most programmers do. For the processor the memory isn’t an array of bytes, but rather an array of blocks. In the case of the x86 processor this is usually 4 bytes.&lt;/p&gt;
&lt;p&gt;When I got a simple piece of code like ‘&lt;code&gt;(*i)++&lt;/code&gt;‘ the processor will find the 4 byte block in which this 4 byte integer &lt;code&gt;i&lt;/code&gt; is located, increments it and stores it.&lt;/p&gt;
&lt;p&gt;Well.. it does this when &lt;code&gt;i&lt;/code&gt; fits exactly in one block. When &lt;code&gt;i&lt;/code&gt; is partially in one block, and the rest is in a second block (it is unaligned) the processor will have to fetch both blocks, reconstruct the integer, increment it, split it, and store it back.&lt;/p&gt;
&lt;p&gt;This is a lot of extra work. The processor will spend a few times more work on a simple increment. Although the actual difference is only about 5% because requesting 2 blocks or 1 block doesn’t differ that much.&lt;/p&gt;
&lt;p&gt;Because this means a lot of extra work for the processor, and even more transistors, some processor manufacturers decided to barely or not support unaligned data.&lt;/p&gt;
&lt;p&gt;Summarized:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some processors will just cope with unalligned data, although it takes a bit more time. (x68)&lt;/li&gt;
&lt;li&gt;Other’s will throw an hardware exception and let the OS fix it up, which takes a hell of a lot more time.&lt;/li&gt;
&lt;li&gt;A bunch will get unstable and the process crashes, or the whole processor will.&lt;/li&gt;
&lt;li&gt;Ans some will silently ignore the unaligned data using the first aligned data that comes close instead which leads to silent corruptions and hard to trace bugs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="bliss-of-c"&gt;Bliss of C&lt;/h3&gt;
&lt;p&gt;Maybe this will shock you, at least it shocked me. Luckily you don’t need to worry a lot when you aren’t writing specific low-level applications like memory managers or compilers. Your C compiler will take care of alignment for you.&lt;/p&gt;
&lt;h3 id="gimmi-more"&gt;Gimmi more&lt;/h3&gt;
&lt;p&gt;Kaja wrote &lt;a href="http://www.entertheunknown.net/2005/10/23/the-truth-about-memory-alignment/"&gt;an article about memory alignment&lt;/a&gt;.&lt;br&gt;
IBM has got an &lt;a href="http://www-128.ibm.com/developerworks/library/pa-dalign/"&gt;excelent article&lt;/a&gt; on it too.&lt;/p&gt;</description></item><item><title>Enter HashCash 3.0</title><link>https://blog.affien.com/archives/2005/10/23/enter-hashcash-30/</link><pubDate>Sun, 23 Oct 2005 22:26:07 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/23/enter-hashcash-30/</guid><description>&lt;p&gt;A new anti-wordpress-spam release of Elliott Back: &lt;a href="http://elliottback.com/wp/archives/2005/10/23/wordpress-hashcash-30-beta/"&gt;HashCash 3.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Basicly it uses md5, javascript and a bit of AJAX, which is very hard to force except when a spam bot executes the actual javascript.&lt;/del&gt;&lt;ins&gt;Basicaly it just keeps an â€œundecipherableâ€ secret which in theory youâ€™d need javascript to decode.&lt;/ins&gt; The problem with that is that it takes some time to execute the javascript and hopefully will scare the spambot away.&lt;/p&gt;
&lt;p&gt;The method isn’t intrusive (although it does require javascript to be turned on), and pretty effective.&lt;/p&gt;
&lt;p&gt;Good work Elliot!&lt;/p&gt;</description></item><item><title>Paradox Wiki</title><link>https://blog.affien.com/archives/2005/10/19/paradox-wiki/</link><pubDate>Wed, 19 Oct 2005 01:16:15 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/19/paradox-wiki/</guid><description>&lt;p&gt;&lt;a href="http://entertheunknown.net/"&gt;Kaja&lt;/a&gt; has set up a &lt;a href="http://entertheunknown.net/wiki/index.php/Main_Page"&gt;wiki for paradox&lt;/a&gt; to document his Compiler + JIT + Interpreter in the making.&lt;/p&gt;
&lt;p&gt;I added &lt;a href="http://entertheunknown.net/wiki/index.php/IMGC"&gt;quite some documentation about my Garbage Collector IMGC&lt;/a&gt; there too for it will be used by Paradox.&lt;/p&gt;</description></item><item><title>Back from Rome</title><link>https://blog.affien.com/archives/2005/10/15/back-from-rome/</link><pubDate>Sat, 15 Oct 2005 10:40:09 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/15/back-from-rome/</guid><description>&lt;p&gt;I`m back indeed.&lt;/p&gt;
&lt;p&gt;Rome is a great city.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Giolitti&lt;/em&gt;‘s ice-cream tastes great as does &lt;em&gt;tazza d’oro&lt;/em&gt;‘s espresso.&lt;/p&gt;
&lt;p&gt;Best building I visited was the pantheon. I like it more than the sixtian chapel, which is overrated in my humble opinion.&lt;/p&gt;
&lt;p&gt;(Go Bernini! Boo Michelangolo)&lt;/p&gt;
&lt;p&gt;Anyway, I could fill a few pages with my experiences, but I`m to lazy and too excited with my new toy: &lt;a href="http://reader.google.com/"&gt;google reader&lt;/a&gt;!&lt;/p&gt;</description></item><item><title>Rome, here I come</title><link>https://blog.affien.com/archives/2005/10/05/rome-here-i-come/</link><pubDate>Wed, 05 Oct 2005 17:46:59 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/05/rome-here-i-come/</guid><description>&lt;p&gt;I’ll be on a school excursion to Rome for 10 days, from tomorrow Thursday the 6th of October untill Saterday the 15th of October.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;NB&lt;/ins&gt; Contact my twin, Bram, if you would have contacted me.&lt;/p&gt;
&lt;p&gt;&lt;a href="mailto:bram.westerbaan@gmail.com"&gt;bram.westerbaan@gmail.com&lt;/a&gt;&lt;/p&gt;</description></item><item><title>My wordpress.com blog finally has got an usage</title><link>https://blog.affien.com/archives/2005/10/02/my-wordpresscom-blog-finally-has-got-an-usage/</link><pubDate>Sun, 02 Oct 2005 01:32:25 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/02/my-wordpresscom-blog-finally-has-got-an-usage/</guid><description>&lt;p&gt;The &lt;a href="http://baswesterbaan.wordpress.com/"&gt;free wordpress.com blog I got&lt;/a&gt; will be used to dump my stupidest, most impulsive and chaotic thoughts or things I want to say.&lt;/p&gt;
&lt;p&gt;You’re warned.&lt;/p&gt;</description></item><item><title>Binary Multiples</title><link>https://blog.affien.com/archives/2005/10/01/binary-multiples/</link><pubDate>Sat, 01 Oct 2005 12:34:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/10/01/binary-multiples/</guid><description>&lt;p&gt;Data size prefixes always have caused confusion.&lt;/p&gt;
&lt;p&gt;How much is one MB?&lt;/p&gt;
&lt;p&gt;Originally it’s 1024 kB, each kB is 1024B. This makes a total of 1024&lt;sup&gt;3&lt;/sup&gt; bytes (1073741824).&lt;/p&gt;
&lt;p&gt;Using 1024 instead of 1000 has its roots in the fact that computers usually work with blocks of 1024 bytes (2&lt;sup&gt;10&lt;/sup&gt;).&lt;/p&gt;
&lt;p&gt;Other people stick to the SI and deem one MB 1000&lt;sup&gt;3&lt;/sup&gt; bytes (1000000000).&lt;/p&gt;
&lt;p&gt;To get rid of confusion binary multiples were introduced. One MiB = 1024&lt;sup&gt;3&lt;/sup&gt;, where one MB would be 1000&lt;sup&gt;3&lt;/sup&gt;.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Factor&lt;/th&gt;
 &lt;th&gt;Name&lt;/th&gt;
 &lt;th&gt;Symbol&lt;/th&gt;
 &lt;th&gt;Factor&lt;/th&gt;
 &lt;th&gt;Name&lt;/th&gt;
 &lt;th&gt;Symbol&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;1&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Kilo&lt;/td&gt;
 &lt;td&gt;k&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;1&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Kibi&lt;/td&gt;
 &lt;td&gt;Ki&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;2&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Mega&lt;/td&gt;
 &lt;td&gt;M&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;2&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Mebi&lt;/td&gt;
 &lt;td&gt;Mi&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;3&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Giga&lt;/td&gt;
 &lt;td&gt;G&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;3&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Gibi&lt;/td&gt;
 &lt;td&gt;Gi&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;4&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Tera&lt;/td&gt;
 &lt;td&gt;T&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;4&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Tebi&lt;/td&gt;
 &lt;td&gt;Ti&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;5&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Peta&lt;/td&gt;
 &lt;td&gt;P&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;5&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Pebi&lt;/td&gt;
 &lt;td&gt;Pi&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;6&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Exa&lt;/td&gt;
 &lt;td&gt;E&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;6&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Exbi&lt;/td&gt;
 &lt;td&gt;Ei&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Zetta&lt;/td&gt;
 &lt;td&gt;Z&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;7&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Zebi&lt;/td&gt;
 &lt;td&gt;Zi&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;1000&lt;sup&gt;8&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Yotta&lt;/td&gt;
 &lt;td&gt;Y&lt;/td&gt;
 &lt;td&gt;1024&lt;sup&gt;8&lt;/sup&gt;&lt;/td&gt;
 &lt;td&gt;Yobi&lt;/td&gt;
 &lt;td&gt;Yi&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;When buying something one should take notice of this, because the difference between one GB and one GiB is 74MB (or 70 MiB).&lt;/p&gt;
&lt;p&gt;With ever increasing storage capability there would be a time where one VendekaByte would be half of one VendebiByte. (Vendika = 10&lt;sup&gt;30&lt;/sup&gt;)&lt;/p&gt;</description></item><item><title>Downtime</title><link>https://blog.affien.com/archives/2005/09/29/downtime-2/</link><pubDate>Thu, 29 Sep 2005 20:34:43 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/29/downtime-2/</guid><description>&lt;p&gt;Sorry for the downtime, it seems that the vServer software hosting this site crashed.&lt;/p&gt;</description></item><item><title>The GC: Tracing, reversing pointer to object</title><link>https://blog.affien.com/archives/2005/09/25/the-gc-tracing-reversing-pointer-to-object/</link><pubDate>Sun, 25 Sep 2005 20:06:45 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/25/the-gc-tracing-reversing-pointer-to-object/</guid><description>&lt;h3 id="the-problem"&gt;The problem&lt;/h3&gt;
&lt;p&gt;Whilest tracing down garbage during the Garbage Collection, as described in earlier posts, it is required to find mark an object pointed to from another object.&lt;/p&gt;
&lt;p&gt;This could lead to problems when it is allowed to point anywhere inside an object, or when the object information bit can’t be found by a pointer to the start of the object.&lt;/p&gt;
&lt;p&gt;In both cases the Gc should somehow translate a pointer (eg. &lt;code&gt;0x1234&lt;/code&gt;) to the head of the object it points in (eg. &lt;code&gt;0x1200&lt;/code&gt;). The problem here is how to efficiently get &lt;code&gt;0x1200&lt;/code&gt; from &lt;code&gt;0x1234&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="avoiding-the-problem"&gt;Avoiding the problem&lt;/h3&gt;
&lt;p&gt;This problem can be circumvented by disallowing pointers pointing to inside the object and instead require all pointers to point to the start of the object. This will only work when the header of the object has a fixed size, otherwise it will still be impossible to work back to the start of the header, which contains the flags you want to alter when tracing garbage.&lt;/p&gt;
&lt;p&gt;Pointers inside a managed object aren’t required and could easily be removed. They can be very usefull though in some situations. One of these situations is being able to inline a private referenced instance into the contained class, of which is known that it won’t be modified, which would result in pointers inside the container class. It will only increase performance in some situations, but it will be usefull to have, and is optional.&lt;/p&gt;
&lt;p&gt;A bigger issue are pointers that point to the start of an object with a header in front of it which has got a dynamic size. Either the header shouldn’t be of dynamic size, and a fixed (big) size, or instead of to the start of the object, pointers should point to the header of an object. In the latter case each pointer derefence should require an ‘add’ call to increase the address to match the start of the object, with the additional logic required to attain the size of the header which can be significant depending on the implementation. These extra opcodes for each pointer derefence could not be easily be worked away even when using a JIT because of multi-threading, and certainly could not be avoided when using C. The fixed header size isn’t nice either. For it probably would end up being at least 7 bytes on a 64bit platform (flags + pointer).&lt;/p&gt;
&lt;p&gt;Oh, and there is also the &lt;em&gt;java&lt;/em&gt; way which uses a handle for each object. Which basicly means that an integer pointer isn’t int*, but int** in java. Where the pointer in between contains the meta-data about the object. This is even more less ideal for it requires an extra derefence for each derefence and it results in twice the amount of pointers to track.&lt;/p&gt;
&lt;p&gt;As far as I concern this problem &lt;strong&gt;can’t be avoided&lt;/strong&gt;, when dealing with a Gc that is required to interop with non-managed code. With a JIT it could be done though, but this requires a runtime performance/garbage collection performance trade-off. And I personally like a bit slower garbage collect instead of slower runtime.&lt;/p&gt;
&lt;h3 id="look-up-structure"&gt;Look-up structure&lt;/h3&gt;
&lt;p&gt;Before tracing the garbage collection usually walks through the heap to mark all objects white and put those in the root-set in the gray-list. During this first walk through the heap a temporary look-up structure could be build to allow efficient look-up during trace.&lt;/p&gt;
&lt;p&gt;When only allowing pointers to the start of the object it would be rather easy to do. A modulus-based bucket like implementation, a hash table without the hash-part, would do. This would allow a nice even redistribution of entries throughout the table, for it uses a modulus.&lt;/p&gt;
&lt;p&gt;When allowing pointers in the middle of an object it becomes more tricky, because you can’t precompute the pointers to put in the table. You need to have a structure which allows you to look to the left and find the object the pointer points into. Although most pointers still point to the start of the object, the case that they could point inside the object shouldn’t be concidered.&lt;/p&gt;
&lt;p&gt;Instead of a modulus-based bucket, division-based buckets should be used. This creates a problem for the likely distribution of blocks between the buckets will vary heavily. One whole bucket could be empty when there is a big allocation in the memory it represents, where almost all small objects which represent most of the pointers could be concentrated in just two buckets.&lt;/p&gt;
&lt;h3 id="bucket-tree"&gt;Bucket-tree&lt;/h3&gt;
&lt;p&gt;To compensate for this a bucket-tree could be used. Basicly when a bucket contains a lot of elements it would split itself in a new set of buckets. This way a minimal amount of buckets could be wasted on really big allocations, and a lot of buckets could be allocated for small allocations. The look-up time would be a bit worse, but it would be neglectable to the huge lookup time a normal search through the heap would require.&lt;/p&gt;
&lt;h3 id="special-treatment-for-pointers-pointing-inside-objects"&gt;Special treatment for pointers pointing inside objects&lt;/h3&gt;
&lt;p&gt;When there are only a one or two pointers in the whole heap that point inside another object they could be treated seperately instead, and the rest could keep using the modulus-based buckets.&lt;/p&gt;
&lt;p&gt;One way to give those pointers a special treatment is marking them, and resolving to which object they point during the initial walk through the heap where finding objects pointed to from pointers is a lot easier. (pointers needed to be looked up could be sorted by address, and be checked during the walk, which is very efficient).&lt;/p&gt;
&lt;p&gt;Another way would be to simulate pointers pointing inside another pointer by making the pointer consist out of an object pointer and a offset from there, which could be cached by the JIT, or expanded before the garbage collection.&lt;/p&gt;
&lt;p&gt;Yet another way would be to walk the modulus-based buckets by hand when the pointer isn’t found.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;best&lt;/em&gt; method would depend on the implementation of the rest of the Gc.&lt;/p&gt;
&lt;h3 id="about-modulus-based-buckets"&gt;About modulus-based buckets&lt;/h3&gt;
&lt;p&gt;I`m still uncertain about whether the distribution in a modulus-based bucket can be trusted at all times. Putting a bucket-tree in default, for worst case would be nice, just to be sure.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update: some more possibilities:&lt;/ins&gt;&lt;/p&gt;
&lt;h3 id="binary-search"&gt;Binary search&lt;/h3&gt;
&lt;p&gt;When we put pointers to all allocated blocks sorted somewhere in the memory, one could use binary search, or other search algorithms to search in sorted lists, to find the pointer. When adding &lt;em&gt;shortcuts&lt;/em&gt; each ~64K this could be quite efficient. I’ve implemented this method for my Garbage Collector temporarily for it is amongst the easier to implement and I suspect the fastest. Actually, I hope it is the fastest.&lt;/p&gt;
&lt;p&gt;I’ll do some tests on different algorithms on a dump of a ‘modal’ application’s managed heap, when I’ve finished the Gc sufficiently to make an application work with it.&lt;/p&gt;</description></item><item><title>The GC: Concurrency</title><link>https://blog.affien.com/archives/2005/09/14/the-gc-concurrency/</link><pubDate>Wed, 14 Sep 2005 21:50:11 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/14/the-gc-concurrency/</guid><description>&lt;p&gt;The &lt;em&gt;tracing Gc&lt;/em&gt;`s (see previous posts) biggest disadvantage is the unpredictability of the garbage collection. It can happen anytime and the time it takes varies. This while normal execution is halted, can cause serious problems to certain applications which are required to have a low latency.&lt;/p&gt;
&lt;h3 id="incremental-gc"&gt;Incremental Gc&lt;/h3&gt;
&lt;p&gt;One trick to improve the latency of the gc is to make the garbage collection &lt;em&gt;incremental&lt;/em&gt;. Instead of doing everything in one big garbage collection, tiny chunks of execution are interchanged with garbage collection.&lt;/p&gt;
&lt;h4 id="generations"&gt;Generations&lt;/h4&gt;
&lt;p&gt;When using a &lt;em&gt;generations gc&lt;/em&gt;, a garbage collector which groups objects by their age, garbage collection could be done on each seperate generation. Objects that have survived a few collections, and settle in older generations, tend to remain persistent. (those are the objects that remain global during the duration of the program). Therefore the older generations don’t need a lot of garbage collections. Whereas the youngest collections typically contain a lot of garbage and require frequent garbage collections.&lt;/p&gt;
&lt;h4 id="granularity"&gt;Granularity&lt;/h4&gt;
&lt;p&gt;Very much small garbage collections could have worse performance than one big garbage collection. Although very big garbage collections which are very infrequent are really bad for latency. When it gets extreme there even could be 100MB allocated memory for 1MB used memory at a moment, because garbage isn’t collected frequently enough. Having a lot of garbage between live data also gets in the way of locality of reference (used memory close together gets all in one load of the L2-cache which is a lot faster than normal RAM).&lt;/p&gt;
&lt;p&gt;Although a figure like 100MB sounds ridiculous, take for instance a program that reads through a text file and print every line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;while there-is-a-new-line
 string line = get-line-from-file
 print line
end
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Every line read would go on the heap as a string. After the &lt;code&gt;line&lt;/code&gt; string goes out of scope it becomes unreferenced from the &lt;em&gt;stack&lt;/em&gt; (part of the root-set) and therefore garbage. When reading a big file the heap fills up pretty fast. When doing another similar operations but then from the lot faster memory than file it could even get worse.&lt;/p&gt;
&lt;p&gt;When doing a lot of garbage collects small pieces of memory are copied each time over short distances, which is less efficient than bigger pieces, but having to copy pieces over a very great distance, which doesn’t fit in the L2-cache really slows down instead of speeding up.&lt;/p&gt;
&lt;h4 id="trace-only-garbage-collections"&gt;Trace-only garbage collections&lt;/h4&gt;
&lt;p&gt;When a lot of memory is allocated in a short time the garbage collector could get suspicious and fire away a full collection, which could be a waste of time when all allocated memory seems to still be live. Moving memory, marking freespaces and updating pointers takes most time of the whole garbage collection. When only tracing what is garbage and what isn’t and after that deciding what to do could provide a gain in performance.&lt;/p&gt;
&lt;p&gt;Not only does tracing down garbage take less time, it also is easier to do while the rest of the program is running.&lt;/p&gt;
&lt;h4 id="internal-data-garbage-collections"&gt;&lt;em&gt;Internal data&lt;/em&gt; garbage collections&lt;/h4&gt;
&lt;p&gt;Most gc’s keep internal data structures optimized for quick access and modification for thing like tracking types, freeblocks, blocks, unmanaged pointers and others. An example could be a list which contains the pointers to unmanaged pointers to be able to link into managed memory from unmanaged memory. This list would be accessed a lot when in unmanaged code, which requires all pointers on its unmanaged stack to be registered on that list.&lt;/p&gt;
&lt;p&gt;A chained-block stack would perform best. The whole stack contains out of a few chained blocks, where the last block is pointed to from the stack structure, which on itself points to the previous block, and so on all the way to the first block. Adding a pointer-pointer to the stack would be as easy as increment the pointer count, and put it in the last block. And possibly creating a new block when the current block is full.&lt;/p&gt;
&lt;p&gt;Removing a pointer-pointer would work best by searching from end to begin for the pointer and simply NULL-ing it. This for the most frequent use for the stack-list would be for registering pointers from the unmanaged stack and deregistering them afterwards. Although when another global unmanaged pointer is registered there could be a few block registered for the stack, where only the very last contains that one single pointer-pointer to that global pointer which won’t be deregistered soon.&lt;/p&gt;
&lt;p&gt;The algorithm could be changed to compact on every operation, or to track freespaces in the stack-list, but it can be done a lot easier. Simply collection the garbage and compacting the stack-list would work just as well.&lt;/p&gt;
&lt;p&gt;It would be tempting to perform these garbage collections for internal structures during the normal garbage collection, but this would hurt latency. Instead scheduling them somewhere in between would be best.&lt;/p&gt;
&lt;h3 id="concurrency"&gt;Concurrency&lt;/h3&gt;
&lt;p&gt;When a garbage collection is in progress all other threads are usually stopped to avoid the program itself (the mutator) to change memory and corrupting the managed heap. Although it is possible to make most parts of the garbage collection concurrent with normal application execution.&lt;/p&gt;
&lt;h4 id="tracing"&gt;Tracing&lt;/h4&gt;
&lt;p&gt;When a pointer is changed during tracing down garbage in an object which already is &lt;em&gt;black&lt;/em&gt; (all pointers in the object have been checked), the object pointer to will remain &lt;em&gt;white&lt;/em&gt; (no black object seems to point to it) and will be scheduled for garbage collection.&lt;/p&gt;
&lt;p&gt;This condition is rare, but it could happen, and it could be fatal. Other conditions like an allocation during trace could be easily solved by marking the object black when allocated.&lt;/p&gt;
&lt;h4 id="write-barrier"&gt;Write barrier&lt;/h4&gt;
&lt;p&gt;An easy way to cope with these conditions is to detect any reading or writing to pointers that already are marked black, and acting upon this. This is called a &lt;em&gt;write barrier&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The problem with a write barrier is that it is very hard to implement for languages like C, and cause a performance hit, for each pointer-derefence+write would require a few extra opcodes, and would be in most cases unacceptible. When you are dealing with a JIT-ed language (Just In Time compiled) however, you can emit these extra opcodes to detect writes into the &lt;em&gt;black&lt;/em&gt; objects only when a Gc is in progress.&lt;/p&gt;
&lt;h4 id="compacting-and-pointer-change"&gt;Compacting and Pointer change&lt;/h4&gt;
&lt;p&gt;After garbage has been traced down it is time for the gc to compact the memory by moving live objects in freed garbage, and changing pointers to these objects accordingly. When traced the gc already would have made a translation table for pointers (usually offset based for efficiency) and would walk its way through the heap compacting and changing pointers in one go.&lt;/p&gt;
&lt;p&gt;When the application is running at that time it would encounter problems when reading dereferencing pointers.&lt;/p&gt;
&lt;h4 id="read-barrier"&gt;Read barrier&lt;/h4&gt;
&lt;p&gt;To combat this a &lt;em&gt;read barrier&lt;/em&gt; would be required. Which is the same as a write barrier, but then for normal pointer-dereferencing. This too requires opcodes to be added on each dereferencing, which would be easy for a JIT and unacceptible for C. The added opcodes would simply look to the place where the garbage collection is at the moment, and convert the pointer as if it was the Gc itself using the Gc’s translation table.&lt;/p&gt;
&lt;h3 id="concurrency-outside-collection"&gt;Concurrency outside collection&lt;/h3&gt;
&lt;p&gt;Making a Gc work concurrent outside a garbage collection is relatively easy for no really collection is happening at runtime and a few rw-locks would do the trick.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Concurrency in a Gc is a must for some applications, and generally a good idea anyway. A better latency can be gained from a fine-coarsed incremental garbage collections. Real concurrency can be gained by using read and write barriers to allow execution during the garbage collection, which is only feasible when working with a JIT.&lt;/p&gt;</description></item><item><title>The GC: Tracing Garbage</title><link>https://blog.affien.com/archives/2005/09/12/the-gc-tracing-garbage/</link><pubDate>Mon, 12 Sep 2005 18:27:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/12/the-gc-tracing-garbage/</guid><description>&lt;p&gt;Most Garbage Collectors are &lt;em&gt;tracing&lt;/em&gt;. Instead of using &lt;em&gt;Reference Counting&lt;/em&gt;, they trace down unused objects (&lt;em&gt;garbage&lt;/em&gt;) by tracing from the &lt;em&gt;root&lt;/em&gt; set of objects and mark all objects found. Those who weren’t marked have to garbage.&lt;/p&gt;
&lt;h4 id="the-root-set"&gt;The Root-set&lt;/h4&gt;
&lt;p&gt;The root-set are all objects that are definitely live objects. The root set typically consists out of the objects linked from the stack and registers of each thread. Also object vital to the Gc and globals are in the root-set.&lt;/p&gt;
&lt;h3 id="tri-color-algorithm"&gt;Tri-Color algorithm&lt;/h3&gt;
&lt;p&gt;An easy way to represent tracing through objects is the tri-color method. There are three colors an object can have: white, gray and black. All white objects haven’t seem to be referenced yet from black objects which are sure to be non-garbage. The gray objects are those that are referenced by black objects but didn’t have all of their references checked. Sounds confusing? A more practical explanation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Colour all objects white.&lt;/li&gt;
&lt;li&gt;Colour the root-set objects gray.&lt;/li&gt;
&lt;li&gt;(Repeat this as long as there are gray coloured objects) Pick a gray object. Colour all objects referenced to from that gray object gray too. (Except those who are black). And colour itself black.&lt;/li&gt;
&lt;li&gt;All black objects are now reachable, and all white objects are unreachable. Free those that are white!&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="pop-mark-push-referenced"&gt;Pop-mark-push referenced&lt;/h4&gt;
&lt;p&gt;An implementation of the Tri-Color algorithm can be accomplished by putting a mark on each object which either can be 1 or 0. 1 representing a black object, and 0 representing a white object. A stack list can be used to keep track of the gray objects:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NB&lt;/strong&gt; do not confuse this stack, which is a normal Last In First Out list with the call stack.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mark all objects 0 (white).&lt;/li&gt;
&lt;li&gt;Push all objects in the root-set on the gray-stack.&lt;/li&gt;
&lt;li&gt;(while there are objects in the gray-stack) Pop an object from the gray-stack. Mark it 1 (black) and push all referenced objects from that object on the gray-stack that aren’t marked 1 (thus white).&lt;/li&gt;
&lt;li&gt;All objects still marked 0 (white) can be freed rid of.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="generations"&gt;Generations&lt;/h3&gt;
&lt;p&gt;Studies have shown that in almost all applications most allocations have a lifetime less than a few miliseconds, although the rest of the allocations would have a far greater lifespan. When collecting every few miliseconds would cause unnesessary tracing through the long living objects which would still take up most of the memory, and when collecting every few seconds the uncollected short-lifed objects would have spammed the heap and would make the garbage collector locality-of-reference unfriendly (everything worked on wouldn’t fit in one l2-cache load and therefore would be a lot slower).&lt;/p&gt;
&lt;p&gt;The older objects which are in comparison with the newer objects highly unlikely to be garbage could be searched less frequently. This could be done by seperating the heap into generations. Each generation is basicly a piece of the heap. A typical garbage collection would only target the youngest few generation. Everytime an object survives a garbage collection it’s moved into an older generation, and finally becomes part of the oldest generation that is only garbage collected very infrequently.&lt;/p&gt;
&lt;h3 id="unpredictable-garbage-collection-duration"&gt;Unpredictable garbage collection duration&lt;/h3&gt;
&lt;p&gt;The duration of the &lt;em&gt;garbage collections&lt;/em&gt; would be hard to predict and could vary a lot. Although &lt;em&gt;generation based gc’s&lt;/em&gt; could increase the amount of &lt;em&gt;garbage collections&lt;/em&gt; and decrease the total time in comparison with one big, applications that use a garbage collection can not guarentee (practically) uninterupted execution.&lt;/p&gt;
&lt;h3 id="advantages"&gt;Advantages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;No extra fields required to keep track of the reference count.&lt;/li&gt;
&lt;li&gt;There hasn’t got to be registration of references to objects, cause the gc keeps traces those down.&lt;/li&gt;
&lt;li&gt;Hasn’t got any problem with circular references.&lt;/li&gt;
&lt;li&gt;Outperforms reference Gc. The registration for each reference in the reference counter Gc takes more time than tracing down that reference. And it doesn’t do unnesessary checking of older objects when generations are kept in mind.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="disadvantages"&gt;Disadvantages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Way harder to implement.&lt;/li&gt;
&lt;li&gt;All pointers inside an object should be known.&lt;/li&gt;
&lt;li&gt;Worse latency than reference counter. Although it outperforms refcounter, a garbage collects usually requires the whole program to be halted, which is a really bad thing for some applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Tracing gc&lt;/em&gt;‘s have shown to easily outperform &lt;em&gt;reference counter gc&lt;/em&gt;‘s. The prerequeste to know all pointers in an object can be solved easily for interpreted and jit-ted languages using the gc and can also be managed even in C with effort. The real problem remains the arbitrary and unpredictable length of garbage collections. There are ways to make tracing gc’s have a better latency, which I`ll discuss in coming posts.&lt;/p&gt;</description></item><item><title>The GC: As A Managed Memory Allocator</title><link>https://blog.affien.com/archives/2005/09/11/the-gc-as-a-managed-memory-allocator/</link><pubDate>Sun, 11 Sep 2005 14:35:25 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/11/the-gc-as-a-managed-memory-allocator/</guid><description>&lt;p&gt;Most Garbage Collectors aren’t limited to just tracing the garbage (unused objects) and scheduling it for deletion, but also manage memory as a whole including allocating it.&lt;/p&gt;
&lt;h3 id="data-segment"&gt;Data segment&lt;/h3&gt;
&lt;p&gt;The kernel of an Operating System takes care of mapping physical memory (RAM/Swap memory/IO memory/Cache’s) to virtual memory available to a process. A process is allocated a few segment’s of memory. The one that is important to memory allocators is the &lt;em&gt;Data Segment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Data Segment&lt;/em&gt; is &lt;em&gt;the&lt;/em&gt; segment which contains memory which is used for random access by the program. The size of the &lt;em&gt;Data Segment&lt;/em&gt; can be changed using the &lt;code&gt;sbrk&lt;/code&gt; or &lt;code&gt;brk&lt;/code&gt; C function, which asks the kernel for more memory to be mapped for the process, which then returns a pointer to the start of the newly allocated space. (providing a negative value will result in decreasing the data segment size).&lt;/p&gt;
&lt;h3 id="malloc"&gt;Malloc&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;non-Gc&lt;/strong&gt; memory manager/allocator are &lt;code&gt;malloc&lt;/code&gt; and its friends. Malloc uses &lt;code&gt;sbrk&lt;/code&gt; to obtain memory for the &lt;em&gt;Data Segment&lt;/em&gt; to allocate memory from as almost all other allocators. It prefixes and suffixes all blocks of free or allocated memory by size fields so it can walk through the whole heap. It puts in each freeblock a pointer to the next and previous freeblock, which makes freeblocks easy to insert and find.&lt;/p&gt;
&lt;p&gt;Freeing a block is simply adding into the freeblock chain and setting a bit to flag it is a free block. Allocating a block is simply walking the freeblock chain until a freeblock is found that can hold the required size, and adds new size’s and flags to the new freeblock and updates the pointers one block previous and next into the freeblock chain to match the new offset of the freeblock.&lt;/p&gt;
&lt;p&gt;The big problem with &lt;code&gt;malloc&lt;/code&gt; is fragmentation. &lt;code&gt;sbrk&lt;/code&gt; could be required to be called to enlarge the heap size to create a freeblock big enough for the allocation although there is enough freespace for that allocation, which is scattered and not contiguous.&lt;/p&gt;
&lt;p&gt;Modern implementations of &lt;code&gt;malloc&lt;/code&gt; feature tricks to prefer perfect fits and automaticly coalesce freeblocks to create bigger blocks, which all makes &lt;code&gt;malloc&lt;/code&gt; a whole lot slower than it should be with still quite a lot of memory fragmentation.&lt;/p&gt;
&lt;h3 id="gc-managed-pointers-and-malloc"&gt;Gc managed pointers and &lt;code&gt;malloc&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Most Gc’s implement their own memory allocator routines instead of using &lt;code&gt;malloc&lt;/code&gt;, usually even overriding the old malloc. This is because Gc’s usually know more about the requirements of the application than &lt;code&gt;malloc&lt;/code&gt; itself.&lt;/p&gt;
&lt;p&gt;It gets even better when the Gc knows all pointers to the managed heap. In this case a Gc could decide to move an object, update the pointers that linked to it, and save a lot of space from fragmentation. This is easily implemented when dealing with a interpreted language which uses a Gc for it knows all types runtime. It even can be done in C, but that requires all pointers both inside as outside the managed heap that point into the managed heap to be registered.&lt;/p&gt;
&lt;p&gt;The difficult part is to find all pointers pointing to a certain object. This usually requires the whole heap to be walked, once or twice. Waiting until a reasonable amount of objects would be subject to move, and then doing one big move of all those objects, and possibly other operations requiring heap walks while doing it anyway as one big “garbage collection” would be way more efficient than doing this all ‘live’. In the first pass each object subject to move could be tagged with the new location and on the second pass all pointers would be checked and adjusted accordingly.&lt;/p&gt;
&lt;h3 id="unmanaged-code-interop"&gt;Unmanaged code interop&lt;/h3&gt;
&lt;p&gt;The big problem of being able to move managed memory is keeping track of all pointers into the managed memory. If you would want to store a file handle in managed memory you would have a hard time when the internals of file access keep contain pointers to your file handle.&lt;/p&gt;
&lt;p&gt;Fixed allocations, which remain stationary would solve the issue but this could, sadly enough, result in fragmentation of your heap. When all objects can be moved it is very easy to move, but when there are fixed objects somewhere in the heap, complicated ‘fitting’ algorithms must be used which decrease performance.&lt;/p&gt;
&lt;p&gt;Fixing memory temporarily, or preventing a GC temporarily is a much cleaner solution to the problem. In some cases this just isn’t possible and big blocks with their own &lt;code&gt;malloc&lt;/code&gt; style allocator could be used to handle unmanaged memory so that it won’t interfere too much with the normal managed memeory. On most *nix systems &lt;code&gt;mmap&lt;/code&gt; could be used to map additional usable memory to the virtual memory space of the process. Which is slower than bsrk and create some extra overhead, but it will avoid fragmentation in managed heap due to fixed blocks.&lt;/p&gt;
&lt;h3 id="when"&gt;When&lt;/h3&gt;
&lt;p&gt;It is only usefull for a Gc to implement its own malloc when it can move its objects, or when there is a clear advantage to implementing the &lt;code&gt;malloc&lt;/code&gt; close to the Gc, which could be for instance to more easily walk through all objects in the heap without having to implement a walk algorithm for each malloc used accross different platforms.&lt;/p&gt;</description></item><item><title>The GC: Reference Counter</title><link>https://blog.affien.com/archives/2005/09/11/the-gc-reference-counter/</link><pubDate>Sun, 11 Sep 2005 13:53:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/11/the-gc-reference-counter/</guid><description>&lt;p&gt;The simplest form of Garbage Collector is the Reference Counter Garbage Collector.&lt;/p&gt;
&lt;p&gt;Each time an object is referenced (a pointer to it is made) the reference count on the object is incremented. If the pointer isn’t used anymore the reference count is decreased. If the reference count hits 0 the object will be freed.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://python.org/"&gt;Python&lt;/a&gt; uses a Reference Counter.&lt;/p&gt;
&lt;h3 id="advantages"&gt;Advantages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A reference counter does its tracking at runtime. There is no big garbage collection, and the execution of the program won’t be interupted for a while when the garbage is collected.&lt;/li&gt;
&lt;li&gt;It’s very easy to implement.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="disadvantages"&gt;Disadvantages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Instead of the required &lt;code&gt;malloc&lt;/code&gt; &lt;code&gt;free&lt;/code&gt; pair required for each allocation without Gc, it now requires &lt;code&gt;add_ref&lt;/code&gt; &lt;code&gt;free_ref&lt;/code&gt; for each pointer/reference to an allocation. When someone forgets to release its reference the object persists.&lt;/li&gt;
&lt;li&gt;Circular references will never be collected. An example of a circular reference is a list that contains as an item a reference to itself. When the list is released its count will remain 1 because inside the list it refers to itself and will therefore never be collected.&lt;/li&gt;
&lt;li&gt;A RefCounter GC doesn’t keep track of pointers into the managed heap, and therefore can’t move any object because it`ll break pointers. This makes the fragmentation of the RefCounter GC as bad as &lt;code&gt;malloc&lt;/code&gt;‘s fragmentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="circular-references"&gt;Circular references&lt;/h3&gt;
&lt;p&gt;Circular references can be fixed by adding a &lt;em&gt;trace&lt;/em&gt; algorithm. This algorithm will trace through all objects from the root objects (pointers on the stack, etc.) and mark them. The objects that aren’t marked aren’t accessible and therefore are subject to Garbage Collection.&lt;/p&gt;
&lt;p&gt;The problem is that a RefCounter Gc usually doesn’t keep track of what pointers are in objects, and that there could be pointers outside the managed heap which only use the &lt;code&gt;add_ref&lt;/code&gt; and &lt;code&gt;free_ref&lt;/code&gt;. Python struggled with this problem and it implemented the a trace algorithm that depended on the programmer’s of not-python-modules (of which pointers aren’t known) to implement the list of references to objects that also contain objects. By traversing links that way circular dependencies could be found without hurting unmanaged pointers, but this has a high performance hit on Python, and it is still adviced to avoid circular references.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;RefCounter Gc’s are easy to implement, and a good idea for scripting languages which know all references so that circular references can be dealt with accoringly. But they still have a lot of disadvantages which other kinds of Gc’s solve a lot better, and more elegantly.&lt;/p&gt;</description></item><item><title>The GC: Introduction</title><link>https://blog.affien.com/archives/2005/09/11/the-gc-introduction/</link><pubDate>Sun, 11 Sep 2005 11:38:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/11/the-gc-introduction/</guid><description>&lt;p&gt;I’ve been working on Garbage Collectors recently, and I`ll share some of my experiences with them with you on my blog.&lt;/p&gt;
&lt;p&gt;First off, what is a Garbage Collector?&lt;/p&gt;
&lt;p&gt;A Garbage Collector, a.k.a GC is an algorithm that keeps track of your objects in the memory and gets rid of objects that aren’t used (referenced to) anymore, a.k.a garbage collecting. This can only be accomplished when the GC knows all pointers to the objects managed (objects on the managed part of the heap). And they are therefore almost always used with an interpreted/jit-ted language, like Java, Python or C#.&lt;/p&gt;
&lt;p&gt;Since the first GC’s (reference counters) they have gained a lot more responsibility and perform a lot more tasks, where collecting the garbage is just one of the things they do.&lt;/p&gt;
&lt;p&gt;I`ll discuss the various kinds and aspects of Garbage Collectors with their advantages and disadvantages in coming blog posts.&lt;/p&gt;
&lt;p&gt;You can read all articles about the gc in &lt;a href="http://blog.w-nz.com/archives/category/computer-science/intermediate-languages/gc/"&gt;its category&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Spam, spam and more spam</title><link>https://blog.affien.com/archives/2005/09/11/spam-spam-and-more-spam/</link><pubDate>Sun, 11 Sep 2005 11:23:34 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/11/spam-spam-and-more-spam/</guid><description>&lt;p&gt;I noticed I had an enourmous amount of spam in my moderation queue.&lt;/p&gt;
&lt;p&gt;The plugin I used to protect myself from spam wp-hashcash, seemed to have been mastered by spammers.&lt;/p&gt;
&lt;p&gt;A download of the newest version did the trick.&lt;/p&gt;
&lt;p&gt;If anyone experiences problems with posting comments, please &lt;a href="mailto:bas.westerbaan@gmail.com"&gt;mail me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update I: Seems &lt;em&gt;some&lt;/em&gt; spam prevailed even over this version. I’d better get to making my own custom changes to wp-hashcsah.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update II: I changed the secret codes in the plugin. And I broke it for a while. Either one of those could have resulted in the fortunate (hopefully not temporarilly) stop of spam.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update III: According to Elliot Back, the creator of hashcash, the spammers bruteforce the secret value. Changing it usually is efficient enough to keep them at bay for a while. He’s working on a newer version which features bigger, thus harder to bruteforce values. I just hope they won’t suck my bandwidth &lt;strong&gt;too&lt;/strong&gt; much.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update IV: Unfortunately there seems to be a lot of computing power or a hack behind the breaking of the hashcash security -_-, I keep getting spam :-/&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>Yesterdays Crash</title><link>https://blog.affien.com/archives/2005/09/02/yesterdays-crash/</link><pubDate>Fri, 02 Sep 2005 18:16:44 +0100</pubDate><guid>https://blog.affien.com/archives/2005/09/02/yesterdays-crash/</guid><description>&lt;p&gt;I`m sorry for today’s and yesterday’s downtime.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;@noud, please don’t play with home brewed assembly in root the next time.&lt;/small&gt;&lt;/p&gt;</description></item><item><title>B-Day</title><link>https://blog.affien.com/archives/2005/08/30/b-day/</link><pubDate>Tue, 30 Aug 2005 20:19:15 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/30/b-day/</guid><description>&lt;p&gt;Today it’s my birthday :-). My 17th to be exact.&lt;/p&gt;</description></item><item><title>Quantumic FS</title><link>https://blog.affien.com/archives/2005/08/28/quantumic-fs/</link><pubDate>Sun, 28 Aug 2005 14:17:30 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/28/quantumic-fs/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Recently most linux file systems are atomic. An operation is either performed fully or not at all.&lt;/p&gt;
&lt;p&gt;QNTFS even goes further down. Quantumic operations. Something is done, or not done, or done and not done at the same time, depending on the reader, everytime.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Strange pagerank</title><link>https://blog.affien.com/archives/2005/08/23/strange-pagerank/</link><pubDate>Tue, 23 Aug 2005 23:33:41 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/23/strange-pagerank/</guid><description>&lt;p&gt;Google uses &lt;em&gt;pagerank&lt;/em&gt; to give a site a ranking of importance. Pagerank is strange.&lt;/p&gt;
&lt;p&gt;One thing to note is that pagerank is logarithmic-ish. A pagerank of 2 is a lot better than just the double of pagerank 1.&lt;/p&gt;
&lt;p&gt;By far the most visited site on my server, this blog, has got a page rank of 3.&lt;/p&gt;
&lt;p&gt;Other pages on my server which are visited sometimes like w-nz.com, board.w-nz.com have got a pagerank of 2.&lt;/p&gt;
&lt;p&gt;What catched my attention is that the page &lt;a href="http://xr12.com"&gt;xr12.com&lt;/a&gt;, which basicly is a filler containing a link to the &lt;a href="http://xr12.com/wiki"&gt;xr12 wiki&lt;/a&gt; has got a pagerank of &lt;strong&gt;5&lt;/strong&gt;. This is the same pagerank as a big site like &lt;a href="http://newgrounds.com"&gt;newgrounds&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Maybe google values xr12.com a lot because it is about one topic and is the only site about that topic and that is xr12.com, where this blog has got tons of links about practicly everything from very various sources.&lt;/p&gt;
&lt;p&gt;Pagerank itself isn’t the sorting factor for google but rather the context, although pagerank still is an indicator. Maybe google values a few links which are very specific above tons of links about very different topics.&lt;/p&gt;</description></item><item><title>Using template variables in extension tags with Mediawiki</title><link>https://blog.affien.com/archives/2005/08/23/using-template-variables-in-extension-tags-with-mediawiki/</link><pubDate>Tue, 23 Aug 2005 16:32:13 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/23/using-template-variables-in-extension-tags-with-mediawiki/</guid><description>&lt;p&gt;&lt;a href="http://mediawiki.org/"&gt;Mediawiki&lt;/a&gt;, the wiki used by &lt;a href="http://wikipedia.org"&gt;wikipedia&lt;/a&gt;, is a powerfull wiki.&lt;/p&gt;
&lt;p&gt;It allows you to include self made templates which you can pass variables too. A very usefull template on wikipedia is the stub template. When you add &lt;code&gt;{{stub}}&lt;/code&gt; at the start of an article it will insert text explaining the user that the article isn’t finished yet, but rather a stub. With {{Album_infobox|Name=Sehnsucht|Cover=Sehnsucht_cover.jpg|…}} an infobox is inserted used at wikipedia for all albums.&lt;/p&gt;
&lt;p&gt;When the features of wikipedia don’t suffice you don’t neccessarily have to hack wikipedia to add features. You can add an extension which hooks into a part of the parser to create your own logic for your own custom tags.&lt;/p&gt;
&lt;p&gt;I created &lt;a href="http://w-nz.com/wyrics"&gt;a wiki&lt;/a&gt; to store the lyrics which I already got on &lt;a href="http://board.w-nz.com/index.php?showforum=22"&gt;a forum&lt;/a&gt; and found espacially templates usefull.&lt;/p&gt;
&lt;p&gt;However, there was a slight annoyance when working with templates. The problem is that in several cases there is a link in a template which can be ambiguous (there are two songs called the same) but you don’t want an ugly suffix after the name (like “Deliverance (Album of Opeth)” instead of “Deliverance”). To solve this you have to pass both the name of the album and the name of the page of the album, but this is annoying to do everytime.&lt;/p&gt;
&lt;p&gt;MediaWiki knows no logic so I thought to solve this by adding some basic logic in a custom tag which either uses the same text as the page name when no custom text is specified and otherwise uses the custom text. But that just wouldn’t work.&lt;/p&gt;
&lt;p&gt;MediaWiki, when parsing a page, first escapes all nowiki elements, extensions, comments, links and so on by a unique ID. Then parsed the format and replaced variables with their values. After that it just replaced the unique id’s back with the proper content, which in this case was the output of my extension too, which was flawed because the variables weren’t replaced before the extension tag was escaped out and also because the wiki-link (&lt;code&gt;[[pagename]]&lt;/code&gt;) wasn’t replaced because the extension was still escaped. So I ended up with having &lt;code&gt;[[{{{album}}}]]&lt;/code&gt; on my page instead of a Sehnsucht link.&lt;/p&gt;
&lt;p&gt;Trying to fetch template variables inside the extension just wouldn’t work because the extension was evaluated at the moment it was already included in the main page. Avoiding this by disabling the cache would require parsing the whole template each time it is viewed which is very extensive. (each link on a page in a wiki has to be looked up when parsed to see whether it exists)&lt;/p&gt;
&lt;p&gt;So I googled a bit around and found that &lt;em&gt;Mikesch Nepomuk&lt;/em&gt; submitted a patch on one of the mailinglists to fix this by escaping extensions seperately after the veriables were expanded. Apparently it hadn’t been approved or maybe because it wasn’t included in my release yet so I tried to apply it but it failed. The patch was a bit too old. So I did it by hand instead of by GNUpatch and with some tinkering I got it to work.&lt;/p&gt;
&lt;p&gt;You can download the patch for the 1.5 beta4 &lt;a href="http://blog.w-nz.com/uploads/MediaWiki-ExtensionVariables.patch"&gt;here&lt;/a&gt;, if you are interested.&lt;/p&gt;
&lt;p&gt;And I thought &lt;a href="http://blog.w-nz.com/archives/2005/02/21/why-php-sucks-and-i-still-use-it/"&gt;I would never touch PHP again&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Spread Firefox Clone</title><link>https://blog.affien.com/archives/2005/08/19/spread-firefox-clone/</link><pubDate>Fri, 19 Aug 2005 15:57:25 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/19/spread-firefox-clone/</guid><description>&lt;p&gt;&lt;a href="http://www.spreadinternetexplorer.com/"&gt;SpreadInternetExplorer.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It’s hilarious&lt;/p&gt;</description></item><item><title>Dual Cores, Traffic and Gaming</title><link>https://blog.affien.com/archives/2005/08/17/dual-cores-traffic-and-gaming/</link><pubDate>Wed, 17 Aug 2005 21:49:57 +0100</pubDate><guid>https://blog.affien.com/archives/2005/08/17/dual-cores-traffic-and-gaming/</guid><description>&lt;p&gt;Dual Cores are &lt;em&gt;the&lt;/em&gt; new thing in the processor bussiness. They claim to be perfect for people who want to do different things at the same time but in reality they are just a cheap solution to deliver &lt;em&gt;more&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The truth is that two 500 mhz processors just don’t deliver the calculation power of one 1 000mhz processor. Given offcourse that they are of the same architecture. This is due to the fact that there is a lot of additional logic required to let two processors work together without getting eachother in the way. When two processors both want to write another thing to the same spot of memory you would get impredictable results. To solve this you have all kind of ways to solve it, by for instance locking a region of memory for an amount of time, making the other processor to wait for the first one to finish. But this all creates a lot of overhead and complexity.&lt;/p&gt;
&lt;p&gt;You could compare it with driving a car. Driving a car is relatively easy. You just have to steer around some static obstacles, no big deal. When you know the way you could even do it with your eyes closed. That is unless there are other people driving a car. When driving a car you are keeping an eye, not on the road, but on the other people on the road. This not only slows down your maximum speed or decreases efficiency – you can’t just drive full speed over a junction – but it also increases the complexity and the likelyhood of errors.&lt;/p&gt;
&lt;p&gt;The same thing goes in the case of dual core processors (or even hyper-threaded and normal multi processor platforms). Although the comparison isn’t really valid because having two processors doesn’t mean that you have to do two things at the same time. The issue is though that what you normally would do, would only be done by one processor and you are therefore wasting the other’s capability.&lt;/p&gt;
&lt;p&gt;A good example of this are games. Games tend to be single threaded, which gives best performance for no processor time is wasted to multithreading and it is the easiest thing to do for multithreaded is rather complicated. Complicated enough that there have been a few lengthy discussions in the mono mailing lists how to lock a simple object.&lt;/p&gt;
&lt;p&gt;Because we are getting dual core and propably ‘more’core processors lateron for the companies are too lazy to make decent processors&lt;sup&gt;1&lt;/sup&gt; games should become multithreaded to exploit the full capability of the machine it runs on.&lt;/p&gt;
&lt;p&gt;Although it makes creating performance applications a lot more difficult it will surelly benifit distributed computing for the change from different processors to different machines is less than from 1 processor to more.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;[1] Native threaded CPU’s like dualcores/multi processor/hyperthreaded processors are ideal for server applications where multiple short living requests have to be resolved. Switching an allocating on a software-threaded processor would create too much overhead for such a simple request.&lt;/small&gt;&lt;/p&gt;</description></item><item><title>Practically Reversing CRC</title><link>https://blog.affien.com/archives/2005/07/31/practically-reversing-crc/</link><pubDate>Sun, 31 Jul 2005 19:27:46 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/31/practically-reversing-crc/</guid><description>&lt;p&gt;The algorithm described in my previous post on how to compute a patch for a message to get the wanted crc computed from that text has a usefull application when wanting to get the possible texts that could compute to your own provided crc.&lt;/p&gt;
&lt;p&gt;A little util I wrote, reversecrc (&lt;a href="http://w-nz.com/projects/reversecrc/"&gt;http://w-nz.com/projects/reversecrc/&lt;/a&gt;), lists (the endless) list of possible original texts, has been usefull for the Freelancer modding community, for in that game Crc is used a lot and was an obstacle.&lt;/p&gt;
&lt;p&gt;Although it is almost impossible to reverse a 20 character string because it would be insane to check all the texts that could result in the hash, using one of the provided texts would do too as it results in the same hash anyways.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Subversion repositry: https://cvs.codeyard.net/svn/icrc&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>Opeth’s Ghost Reveries</title><link>https://blog.affien.com/archives/2005/07/21/opeths-ghost-reveries/</link><pubDate>Thu, 21 Jul 2005 21:57:23 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/21/opeths-ghost-reveries/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Swedenâ€™s OPETH and Jens Bogren have finished the recording and mixing of the groupâ€™s latest opus, â€œGhost Reveriesâ€. The album was mastered on Thursday (June 16) at the Cutting Room facilities in Stockholm. The total running time will be around 65 minutes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The two released tracks, &lt;cite&gt;Ghost of Perdition&lt;/cite&gt; and &lt;cite&gt;The Grand Conjuration&lt;/cite&gt; sound promising.&lt;/p&gt;
&lt;p&gt;The album will be for sale on my birthday :-), the 30th of August.&lt;/p&gt;
&lt;p&gt;And they will perform it during their Europian tour, which I`ll visit on the 11th of September in the 013 in Tilburg.&lt;/p&gt;
&lt;p&gt;I`m thrilled.&lt;/p&gt;</description></item><item><title>Reversing CRC</title><link>https://blog.affien.com/archives/2005/07/15/reversing-crc/</link><pubDate>Fri, 15 Jul 2005 12:44:05 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/15/reversing-crc/</guid><description>&lt;h3 id="cyclic-redundancy-code"&gt;Cyclic Redundancy Code&lt;/h3&gt;
&lt;p&gt;CRC is a &lt;a href="http://en.wikipedia.org/wiki/Hash_function"&gt;hash&lt;/a&gt; which is frequently used as a checksum for data in for instance archives. Who hasn’t had &lt;cite&gt;bad CRC&lt;/cite&gt; errors once when opening corrupted zips. CRC is a very old algorithm and over time it changed a lot from the original idea.&lt;/p&gt;
&lt;p&gt;The original idea behind CRC was representing the data that you wanted the hash from as a big number and dividing it by a certain number called the &lt;em&gt;polynomial&lt;/em&gt; and taking the remainder of the division as the hash. For instance: &lt;code&gt;23 % 3 = 2&lt;/code&gt; (&lt;code&gt;%&lt;/code&gt; is the &lt;em&gt;modulus&lt;/em&gt; operator, which is the remainder of a division)&lt;/p&gt;
&lt;p&gt;The initial problem was that dividing is a rather intensive operation. They wanted to simplify CRC to make it easier to implement in hardware and make it faster. They did this by getting rid of the &lt;em&gt;carry&lt;/em&gt; used in the substraction of the division:&lt;/p&gt;
&lt;p&gt;Normal substraction (binary): &lt;code&gt;10101 - 01100 = 01001&lt;/code&gt;&lt;br&gt;
Without carry: &lt;code&gt;&lt;strong&gt;10&lt;/strong&gt;101 - &lt;strong&gt;01&lt;/strong&gt;100 = &lt;strong&gt;11&lt;/strong&gt;001&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Substraction without a carry is basicly a &lt;em&gt;eXclusive bitwise OR&lt;/em&gt; (XOR), which returns only 1 when one of the operands is 1 and the other 0.&lt;/p&gt;
&lt;p&gt;The algorithm required was faster bit still worked bit by bit, which isn’t really what a computer likes. A computer works best with one to four bytes. To make CRC faster they cached 8 operations at the time by precomputing the results for a certain start value and put it in a table called a XOR Table.&lt;/p&gt;
&lt;p&gt;The required code for the CRC calculation itself now became very simple:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hash = (hash &amp;gt;&amp;gt; 8 ) ^ table[data ^ (0xff &amp;amp; hash)]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;They changed the CRC algorithm once more by making it &lt;em&gt;reflected&lt;/em&gt;. This means that the input data is reversed bitwise: &lt;code&gt;011101011&lt;/code&gt; &amp;lt;-&amp;gt; &lt;code&gt;110101110&lt;/code&gt;. This was done because most of the hardware chips at the time reversed data bitwise. For it was too much work to &lt;em&gt;reflect&lt;/em&gt; each byte of incoming data they changed the algorithm that generates the Crc table to create a table which has the effect of reflected data.&lt;/p&gt;
&lt;p&gt;This is by the way not totally correct; the result still was different for a reflected than a non-reflected algorithm for they wouldn’t cache the whole piece of data to reverse it but did it per byte at calculation.&lt;/p&gt;
&lt;p&gt;At this moment CRC barely resembles the original idea of a modulus.&lt;/p&gt;
&lt;h3 id="reversing-crc"&gt;Reversing CRC&lt;/h3&gt;
&lt;p&gt;First off, credits for the original idea of CRC patching go to anarchriz.&lt;/p&gt;
&lt;p&gt;CRC is a cryptographicly very weak algorithm. It can be easily &lt;em&gt;reversed&lt;/em&gt; for it has got the property that with 4 bytes you append to the current computed hash you can get every required hash. You can change the whole message and add 4 &lt;em&gt;patch&lt;/em&gt; bytes to patch the hash to the one you like.&lt;/p&gt;
&lt;p&gt;The ability to patch a CRC also makes it possible to very efficiently generate all possible source data of a checksum. Although it still is a bruteforce method you got 4 bytes freely and patching is faster than calculating.&lt;/p&gt;
&lt;p&gt;Patching is basicly going back the way CRC works. Crc basicly takes the hash, moves it 1 byte to the right (dropping one byte) and xor-ring it with the table entry. The nice thing about normal CRC is that the first byte of a table entry is unique for that entry.&lt;/p&gt;
&lt;p&gt;For the first byte of the entry is unique for that entry and it is put in the hash xor-red with 0 for that is what is shifted in from the right you can work back the whole entry used.&lt;/p&gt;
&lt;p&gt;For instance:&lt;/p&gt;
&lt;p&gt;My is: &lt;code&gt;0x012345678&lt;/code&gt;, this means that it was xorred with the entry in the CRC table that starts with &lt;code&gt;0x12&lt;/code&gt;. When you xor the hash with that full entry the only thing that the next byte was xorred with was the start of a table entry too.&lt;/p&gt;
&lt;p&gt;When reversing the current hash you know what will be xorred on the patch you’ll give. Xorring this with your wanted hash is enough.&lt;/p&gt;
&lt;p&gt;The resulting algorithm is suprisingly simple:&lt;/p&gt;
&lt;p&gt;– Put the current hash byte wise reversed at the start of a buffer. Put the wanted hash byte wise reversed at the end of the current hash in the same buffer.&lt;br&gt;
– Look up the entry in the table that starts with byte 7 in the buffer. Xor this value of position 4, and Xor the entry number on position 3. Repeat this 4 times with the positions each time one decremented. (thus 7,6,5,4 and 4,3,2,1 and 3,2,1,0)&lt;/p&gt;
&lt;p&gt;When you’ve done this the required patch bytes are the first 4 bytes in the buffer.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Some Crc variants tend to use duplicates in the crc-table which means there could be more than one original table entry used. You should just branch and try all of them.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;I’ve made a simple python script to work with crc32 and to patch a hash.&lt;/p&gt;
&lt;p&gt;You can download it &lt;a href="http://w-nz.com/~bas/projects/crc-rev-v0.01b.tar"&gt;Here&lt;/a&gt;. And there is a C implementation &lt;a href="http://cvs.codeyard.net/svn/icrc/trunk/src/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; Fixed a bug in the example.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; Andrea Pannitti wrote an &lt;a href="http://andreapannitti.blogspot.com/2008/01/crc-reverser-java-version.html"&gt;implementation in java&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update&lt;/ins&gt; I found a &lt;a href="http://stigge.org/martin/pub/SAR-PR-2006-05.pdf"&gt;great article&lt;/a&gt; by Stigge, Plï¿½tz, Mï¿½ller and Redlich about reversing CRC. They pretty much nailed it by bringing it down to elementary algebra. They explain an algorithm which is able to patch data at any given point to adjust the CRC to any desired value.&lt;/p&gt;</description></item><item><title>GMail invites</title><link>https://blog.affien.com/archives/2005/07/11/gmail-invites/</link><pubDate>Mon, 11 Jul 2005 17:17:42 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/11/gmail-invites/</guid><description>&lt;p&gt;It seems that &lt;strong&gt;the&lt;/strong&gt; place to get a gmail invite has been closed down: &lt;a href="http://isnoop.net/gmail"&gt;isnoop.net/gmail&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I haven’t got a place anymore to send my gmail invites so I have them spare again.&lt;/p&gt;
&lt;p&gt;If you want a gmail invite, just mail to bas.westerbaan [curly thing] gmail.com.&lt;/p&gt;</description></item><item><title>Linux Mount Security</title><link>https://blog.affien.com/archives/2005/07/10/linux-mount-security/</link><pubDate>Sun, 10 Jul 2005 11:07:53 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/10/linux-mount-security/</guid><description>&lt;p&gt;With the linux &lt;em&gt;Set UID Attribute&lt;/em&gt; you can let the owner of the file be the one the execute it when another user executes the file. This feature has traditionaly be used for system tools in linux which require root access to run but also must be able to be run my users.&lt;/p&gt;
&lt;p&gt;It came to mind that a floppy with the &lt;em&gt;ext2&lt;/em&gt; filesystem could contain files of the &lt;em&gt;root&lt;/em&gt; user with this &lt;em&gt;Set UID Attribute&lt;/em&gt; set. Which theoraticly would allow anyone who is allowed to mount floppy’s or other media with an filesystem that supports this attribute to gain root access for a program.&lt;/p&gt;
&lt;p&gt;On my system I got this entry in my &lt;code&gt;/mnt/fstab&lt;/code&gt;, which allows an user to mount the floppy:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;/dev/floppy/0 /mnt/floppy auto noauto,user 0 0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I made a simple C program which would show the contents of &lt;code&gt;/etc/shadow&lt;/code&gt;, which contains the password hashes of the users, and chmodded it accordingly. (&lt;code&gt;chmod = showshadow; chmod go+x showshadow; chmod u+rs showshadow&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;I ran my program, and it seemed to work! The contents of the &lt;code&gt;/etc/shadow&lt;/code&gt; file was streaming on my console.&lt;/p&gt;
&lt;p&gt;Euforicly I went to another linux computer and tried the same trick.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;darkshines@darkshines-one /mnt/floppy $ ./showshadow&lt;br/&gt;
bash: ./showshadow: Permission denied&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dissapointed but releived it seemed that linux had already some precaution against a root &lt;em&gt;Set UID-ed&lt;/em&gt; executable.&lt;/p&gt;
&lt;p&gt;I copied the contents of the folder whilest preserving permissions to another folder outside the &lt;code&gt;/mnt/floppy&lt;/code&gt; and it all seemed to work again, although I couldn’t do it with a normal user account for I can’t preserve the owner when copying a file as a normal user.&lt;/p&gt;
&lt;p&gt;I wondered how linux would secure it and tried to run the program while it was unchmodded.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;darkshines@darkshines-one /mnt/floppy $ ./showshadow.unchmodded&lt;br/&gt;
bash: ./showshadow.unchmodded: Permission denied&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The warning is from bash which can’t seem to execute the program. (note that it &lt;strong&gt;isn’t&lt;/strong&gt; the program that can’t acces &lt;code&gt;shadow&lt;/code&gt;) . After recompiling it on the floppy itself it seems that linux prevents any program to be executed in an user mounted folder.&lt;/p&gt;
&lt;p&gt;I recon that that security precaution is a bit too strict. Although copying the file from the medium to a normal folder and then executing is still possible, I find it a bit strange that nothing of the user itself can be executed.&lt;/p&gt;
&lt;p&gt;This could result in trouble when dealing with netmounts where one user can has a share on a server where he puts his files and can access only that mount for space on a terminal, when dealing with an user mount which would be required for security.&lt;/p&gt;</description></item><item><title>London Bombings</title><link>https://blog.affien.com/archives/2005/07/07/london-bombings/</link><pubDate>Thu, 07 Jul 2005 21:25:48 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/07/london-bombings/</guid><description>&lt;p&gt;One thing that amazed me about the bombings is that the people didn’t panic, but remained calm.&lt;/p&gt;
&lt;p&gt;Even though the people of London and the rest of England were hurt, they weren’t terrorized.&lt;/p&gt;
&lt;p&gt;Although it might sound harsh, the terrorists have lost this fight: they gained nothing by these bombings.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update: although it is s a bit inconvenient, this post is my 100th blog post. And currently the 100th comment has been made too.&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>Welcome to 213.133.112.101</title><link>https://blog.affien.com/archives/2005/07/06/welcome-to-213133112101/</link><pubDate>Wed, 06 Jul 2005 00:21:11 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/06/welcome-to-213133112101/</guid><description>&lt;p&gt;When you read this, this page has been served from my virtual server.&lt;/p&gt;
&lt;p&gt;This also means that luckily the whole web content transfer has been a success :-D.&lt;/p&gt;
&lt;p&gt;Sadly things haven’t gone as smoothly with the &lt;em&gt;qmail&lt;/em&gt; configuration for my mail accounts.&lt;/p&gt;
&lt;p&gt;So please mail me to bas.westerbaan@gmail.com instead of my @w-nz.com acccount.&lt;/p&gt;
&lt;p&gt;Even though the minor setback with the mail (which is giving me headaches), it has been rather fun to do. And I learned a lot. (like that putting a restriction on the amount of memory that php uses isn’t just to annoy the customer but just to safe the server from some terribly php scripts)&lt;/p&gt;
&lt;p&gt;When &lt;strong&gt;everything&lt;/strong&gt; is working fine I`ll post some more on setting up your own server.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I desperately need some sleep&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update: seems that there are quite some bugs in the transfer after all: ftp which only recursed a certain amount of times; .htaccess files not being transfered; permissions changing; php sucking too much memory (again); not enough sleep 😛&lt;br/&gt;
But seems to be working right now&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>213.133.112.101</title><link>https://blog.affien.com/archives/2005/07/04/213133112101/</link><pubDate>Mon, 04 Jul 2005 21:50:53 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/04/213133112101/</guid><description>&lt;p&gt;That’s the Ip of the vserver I have bought from &lt;a href="http://greent.info"&gt;greenT&lt;/a&gt;, and to which this site will be transfered within the next week.&lt;/p&gt;
&lt;p&gt;There will certainly be some downtime.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;update: I have installed most of the software, now all that remains is transfering.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;update 2: &lt;a href="http://xr12.com"&gt;Xr12&lt;/a&gt; transfered&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>rel=”nofollow”</title><link>https://blog.affien.com/archives/2005/07/02/relnofollow/</link><pubDate>Sat, 02 Jul 2005 22:51:07 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/02/relnofollow/</guid><description>&lt;p&gt;Quite some time ago google started honouring the &lt;code&gt;rel=&amp;quot;nofollow&amp;quot;&lt;/code&gt; attribute value pair in &lt;code&gt;a&lt;/code&gt; html tags, which should prevent spammers from gaining a high page rank by spamming blogs with comments.&lt;/p&gt;
&lt;p&gt;It is useless.&lt;/p&gt;
&lt;p&gt;Spamming costs almost nothing, if there is a slightest amount of gain in it for the spammers they will keep doing it. Of all those hundred thousands of people visiting blogs and seeing comment spam a few will still follow the link, those few are enough for the spammers.&lt;/p&gt;
&lt;p&gt;One could argue that the websites the comment spam point to now haven’t got a really high pagerank anymore. This is only partially true, for only a selective amount of people install the code to add the &lt;code&gt;rel=&amp;quot;nofollow&amp;quot;&lt;/code&gt; attribute in links that can be spammed. Even though the highest ranking blogs have already installed it, the tons of small blogs are still enough to raise the page rank enourmously.&lt;/p&gt;
&lt;p&gt;In my opinion search engines should just ignore links which are considered spam.&lt;/p&gt;</description></item><item><title>Function Recursion Overhead</title><link>https://blog.affien.com/archives/2005/07/01/function-recursion-overhead/</link><pubDate>Fri, 01 Jul 2005 21:22:39 +0100</pubDate><guid>https://blog.affien.com/archives/2005/07/01/function-recursion-overhead/</guid><description>&lt;p&gt;In courses I followed at university and in most books about programming, &lt;em&gt;recursion&lt;/em&gt; is praised as a good way to solve some problems.&lt;/p&gt;
&lt;p&gt;An example of recursion (not-existing-api used for the sake of simplicity):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;int GetFolderSize(Folder folder)&lt;br/&gt;
{&lt;br/&gt;
 int sum = 0;&lt;br/&gt;
 foreach(File file in folder.files)&lt;br/&gt;
 {&lt;br/&gt;
  sum += file.Size;&lt;br/&gt;
 }&lt;br/&gt;
 foreach(Folder subFolder in folder.folders)&lt;br/&gt;
 {&lt;br/&gt;
  sum += GetFolderSize(subFolder);&lt;br/&gt;
 }&lt;br/&gt;
 return sum;&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This example function calculates the combined size of all files in a folder and those inside any subfolder.&lt;/p&gt;
&lt;p&gt;It does its job and it is very clear how it works, but it is inefficient, take another way to write the algorithm:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;int GetFolderSize(Folder folder)&lt;br/&gt;
{&lt;br/&gt;
 Stack&amp;lt;Folder&amp;gt; stack = new Stack&amp;lt;Folder&amp;gt;();&lt;br/&gt;
 int sum = 0;&lt;br/&gt;
 stack.Push(folder);&lt;br/&gt;
 while(stack.Count &amp;gt; 0)&lt;br/&gt;
 {&lt;br/&gt;
  Folder folder = stack.Pop();&lt;br/&gt;
  foreach(File file in folder.files)&lt;br/&gt;
  {&lt;br/&gt;
   sum += file.Size;&lt;br/&gt;
  }&lt;br/&gt;
  foreach(Folder subFolder in folder.folders)&lt;br/&gt;
  {&lt;br/&gt;
   stack.Push(subFolder);&lt;br/&gt;
  }&lt;br/&gt;
 }&lt;br/&gt;
 return sum;&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This version is harder to understand. Basicly it maintains a stack of folder of which the total size of the files in it are not yet calculated. While going through each of the folders in the stack it adds new sub-folders from folders and removes the ones processed.&lt;/p&gt;
&lt;p&gt;The latter method is &lt;em&gt;way&lt;/em&gt; more efficient.&lt;/p&gt;
&lt;p&gt;For each function function call in the first (recursive) version of the algoritm a new &lt;code&gt;sum&lt;/code&gt;-instance, a &lt;code&gt;subFolder&lt;/code&gt;-instance and an enumerator instance over the &lt;code&gt;folder.Folders&lt;/code&gt; is required which stacks up. When 5 deep in the first algorithm you already use more than double of the amount of memory ever required in the second algorithm.&lt;/p&gt;
&lt;p&gt;Additionally a function call itself requires more memory of its own, which depending on the language used, can be quite significant. Debugging also gets really hard when you have got a stack trace of hundreds of functions.&lt;/p&gt;
&lt;p&gt;Using your own stack instead of poluting the call stack (the thing where function calls are kept) sound great. There is only one little problem, it can get pretty complex.&lt;/p&gt;
&lt;p&gt;Take for instance a program that would put the files of folders and their subfolders in a file in that same folder, for instance for a playlist generater. This requires the algorithm to detect when all child items of a certain item have been processed. The problem with this is that the parent item is already gone from the stack when the child item is processed. This requires some additional fields and a few function pointers to get it to work and it can get a mess.&lt;/p&gt;
&lt;p&gt;The best way to get it to work is to mimic what a normal recursive method would have done, which involves a lot of extra helper classes, which all depend on how the original recursive algorithm has worked. In a language with a Garbage Collector (which automaticly free’s unused classes) it is managable, but in a language without it like C(++) trouble doubles when you also need to monitor the lifetime of the helper classes.&lt;/p&gt;
&lt;p&gt;I noticed that it has been very tempting to use recursion and that there are almost no occasions where something like your own stack is used, espacially in the complex cases. A shame, it is challenging :-P.&lt;/p&gt;</description></item><item><title>IEnumerable to IEnumerable&lt;&gt; wrapper</title><link>https://blog.affien.com/archives/2005/06/30/ienumerable-to-ienumerable-wrapper/</link><pubDate>Thu, 30 Jun 2005 23:09:51 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/30/ienumerable-to-ienumerable-wrapper/</guid><description>&lt;p&gt;A simple .net class which maps an &lt;code&gt;IEnumerator&lt;/code&gt; to a generic &lt;code&gt;IEnumerator&lt;t&gt;&lt;/t&gt;&lt;/code&gt;, which is very usefull to convert from generic to non-generic collections.&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System;
using System.Collections;
using System.Collections.Generic;

namespace Intrepid.Collections.Generic
{
	public class EnumerableWrapper&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;
	{
		class EnumeratorWrapper : IEnumerator&amp;lt;T&amp;gt;
		{
			IEnumerator enumerator;
			
			public EnumeratorWrapper(IEnumerator enumerator)
			{
				this.enumerator = enumerator;
			}
			
			public void Dispose()
			{
				// maybe we should dispose the underlying IEnumerable?
			}
			
			public bool MoveNext()
			{
				return enumerator.MoveNext();
			}
			
			public void Reset()
			{
				enumerator.Reset();
			}
			
			object System.Collections.IEnumerator.Current
			{
				get { return enumerator.Current; }
			}
			
			public T Current
			{
				get { return (T)enumerator.Current; }
			}
		}
		
		IEnumerator enumerator;
		
		public EnumerableWrapper (IEnumerable enumerable)
		{
			enumerator = enumerable.GetEnumerator();	
		}
		
		public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()
		{
			return new EnumeratorWrapper(enumerator);
		}
		
		IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return enumerator;
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;</description></item><item><title>Bye Bye Spam</title><link>https://blog.affien.com/archives/2005/06/25/bye-bye-spam/</link><pubDate>Sat, 25 Jun 2005 23:19:54 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/25/bye-bye-spam/</guid><description>&lt;p&gt;I just installed &lt;a href="http://elliottback.com/wp/archives/2005/05/11/wordpress-hashcash-20/"&gt;Hash Cash&lt;/a&gt;, which is an anti spam plugin for WordPress.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hash Cash&lt;/em&gt; protects this blog from spam by requiring the client to execute javascript which calculates a checksum of the content from a seed which is very hard to extract.&lt;/p&gt;
&lt;p&gt;Since I installed it I haven’t got any spam comments :-).&lt;/p&gt;
&lt;p&gt;The downside is that it disallows anyone who hasn’t got a javascript enabled browser to post a comment.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Now I still need to get some good means to combat trackback spam. Just putting them under moderation isn’t good enough for they keep coming&lt;/ins&gt;&lt;/p&gt;</description></item><item><title>Shiftings in Architectures</title><link>https://blog.affien.com/archives/2005/06/25/shiftings-in-architectures/</link><pubDate>Sat, 25 Jun 2005 15:06:59 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/25/shiftings-in-architectures/</guid><description>&lt;h3 id="cell-the-hype"&gt;Cell, the hype&lt;/h3&gt;
&lt;p&gt;Sony is working on a new kind of processor which they call &lt;em&gt;Cell&lt;/em&gt;. A single &lt;em&gt;Cell&lt;/em&gt; processor is said to have a &lt;em&gt;1/75th&lt;/em&gt; of the power of the &lt;em&gt;Blue Gene/L&lt;/em&gt; supercomputer in teraflops, and that for 400 dollars.&lt;/p&gt;
&lt;p&gt;The new Cell processor is hyped, a lot. People are shouting that the performance of the &lt;em&gt;PlayStation 3&lt;/em&gt;, which will feature a Cell processor, will blow away those of the competers: the XBox and the Revolution, both using &lt;em&gt;claimed to be&lt;/em&gt; slow PowerPC processors.&lt;/p&gt;
&lt;h3 id="teraflops"&gt;Teraflops&lt;/h3&gt;
&lt;p&gt;So what are these Teraflops? Why aren’t they talking about Hertzes anymore?&lt;/p&gt;
&lt;p&gt;A TeraFLOPS stands for 1,000,000,000,000 &lt;strong&gt;Fl&lt;/strong&gt;oating point &lt;strong&gt;O&lt;/strong&gt;perations &lt;strong&gt;P&lt;/strong&gt;er &lt;strong&gt;S&lt;/strong&gt;econd. (&lt;a href="http://en.wikipedia.org/wiki/Teraflop"&gt;TeraFLOPS on wikipedia&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;A normal computer has a few GigaFLOPS (one TeraFLOPS is 1000 GigaFLOPS).&lt;/p&gt;
&lt;p&gt;The Cell processor in the PS3 will have 1,8 TeraFLOPS. It is very easy to believe that the PS3 will inheritly be about 500 times faster than a normal computer. But that is false.&lt;/p&gt;
&lt;p&gt;The performance of a computer isn’t all about how fast a computer can calculate with floating point numbers. The performance of a computer has got to do with a lot more than that. Simply doubling the memory performance &lt;ins&gt;(not specificly memory bandwidth, but the whole)&lt;/ins&gt; would have a bigger impact than doubling the amount of TeraFLOPS, even on applications that heavily rely on floating point operations.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;So why have a lot of TeraFLOPS then? It is quite simple, the new platforms haven’t got seperate GPU’s (Graphical Processing Units), their task is now intergrated into the CPU. And what was their task? Calculating, a lot, with floating points.&lt;/del&gt;&lt;br&gt;
&lt;ins&gt;The amount of TeraFLOPS on the new platforms are the sum of the amount of TeraFLOPS of both the GPU and the CPU. A GPU needs to calculate a lot with numbers for 3d rendering.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;Your normal computer has got a lot more than those few GigaFLOPS in your CPU in your GPU already. Although the leap to over the one TeraFLOPS is certainly impressive.&lt;/p&gt;
&lt;h3 id="marketing"&gt;Marketing&lt;/h3&gt;
&lt;p&gt;Super Computers need to do a lot of FLOPS too, they calculate models which got a lot of floating points. So why put the Cell processor in the Ps3 instead of directly in some supercomputer? Simple, marketing. Almost everyone that is superficially following the computer news is telling me over and over again that the Cell processor is the most incredible thing there is. It is hyped.&lt;/p&gt;
&lt;h3 id="linux-on-ps3"&gt;Linux on Ps3&lt;/h3&gt;
&lt;p&gt;Also the Cell processor uses a whole new architecture which still has to be tested a lot to mature. Sony will let you install Linux on your Ps3? Why? Simple, because they want the Linux community to add decent support for the Cell architecture.&lt;/p&gt;
&lt;h3 id="new-architectures--cli"&gt;New Architectures &amp;amp; CLI&lt;/h3&gt;
&lt;p&gt;I guess it will be a matter of time before new architectures will come. A problem with a lot new architectures is that there isn’t a lot of support for them yet. The solution? CLI’s like Java and .Net could bring the solution.&lt;/p&gt;
&lt;p&gt;Microsoft rumoured to have MSIL running (semi)natively on their XBox360 and making Longhorn more and more rely on .Net (&lt;ins&gt;the ontop applications, not the kernel offcourse&lt;/ins&gt;) means a lot less architecture dependency.&lt;/p&gt;
&lt;p&gt;I wonder what will happen, but one thing is sure.. things are shifting.&lt;/p&gt;</description></item><item><title>Python Url Encoding</title><link>https://blog.affien.com/archives/2005/06/25/python-url-encoding/</link><pubDate>Sat, 25 Jun 2005 00:00:20 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/25/python-url-encoding/</guid><description>&lt;p&gt;I looked in the &lt;a href="http://docs.python.org/lib/lib.html"&gt;Python Library Reference&lt;/a&gt; for a function to encode special characters in strings to be able to be put in Urls (and Uri’s), but found none.&lt;/p&gt;
&lt;p&gt;Maybe I missed it?&lt;/p&gt;
&lt;p&gt;Anyways, here is an implementation I wrote based on &lt;a href="http://www.blooberry.com/indexdot/html/topics/urlencoding.htm"&gt;this article&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HexCharacters = &amp;#34;0123456789abcdef&amp;#34;

def UrlEncode(s):
 r = &amp;#39;&amp;#39;
 for c in s:
 o = ord(c)
 if (o &amp;gt;= 48 and o &amp;lt;= 57) or \
 (o &amp;gt;= 97 and o &amp;lt;= 122) or \
 (o &amp;gt;= 65 and o &amp;lt;= 90) or \
 o == 36 or o == 45 or o == 95 or \
 o == 46 or o == 43 or o == 33 or \
 o == 42 or o == 39 or o == 40 or \
 o == 41 or o == 44:
 r += c
 else:
 r += &amp;#39;%&amp;#39; + CleanCharHex(c)
 return r

def CleanCharHex(c):
 o = ord(c)
 r = HexCharacters[o / 16]
 r += HexCharacters[o % 16]
 return r
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;note: I used the character numbers instead the characters to compare with so I could do greater than and lesser than for the alphanumeric numbers. Maybe testing with a bitmask would be more efficient.&lt;/p&gt;
&lt;p&gt;I have to write almost everytime I work with python my own &lt;em&gt;something to hex&lt;/em&gt; function which doesn’t add the ‘0x’ in front the built-in &lt;em&gt;hex&lt;/em&gt; does.&lt;/p&gt;
&lt;p&gt;Either I can’t search or Python hasn’t got enough batteries included. I guess the first, if not I`ll submit my batteries.&lt;/p&gt;</description></item><item><title>Mono gone generic</title><link>https://blog.affien.com/archives/2005/06/17/mono-gone-generic/</link><pubDate>Fri, 17 Jun 2005 23:42:30 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/17/mono-gone-generic/</guid><description>&lt;p&gt;Mono 1.1.8, released yesterday, has implemented the .net2 System.Collections.Generic namespace 😀&lt;/p&gt;
&lt;p&gt;This hasn’t come a moment too early for microsoft will be launching .net2 soon.&lt;/p&gt;</description></item><item><title>BSD</title><link>https://blog.affien.com/archives/2005/06/17/bsd/</link><pubDate>Fri, 17 Jun 2005 23:38:06 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/17/bsd/</guid><description>&lt;p&gt;BSD is Unix.. said to be the professional cousin of Linux.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.forbes.com/intelligentinfrastructure/2005/06/16/linux-bsd-unix-cz_dl_0616theo.html"&gt;This piece of propoganda&lt;/a&gt; for BSD against linux gives as reason that linux is bad for it is told to be just hacked together. This because of the people who develop linux are just people from the community who put a little bit of time in it to get a feature (they probably want) added into Linux and don’t really concern about making it perfect, was said.&lt;/p&gt;
&lt;p&gt;They took some of the sarcastic ‘todo’ comments in the kernel as example, blaming that if that stuff is in the kernel linux can’t be trusted at all.&lt;/p&gt;
&lt;p&gt;But why does BSD hasn’t got the widespread hardware support Linux has? They blame the big company’s like IBM for instance. I just wonder whether their 60 dedicated BSD programmers could code all the hardware drivers that the thousands of contributers of Linux have coded, even if it were as bad as it is now according to them.&lt;/p&gt;
&lt;p&gt;I bet that *BSD has got more than enough of those comments in their code too. If they haven’t they are just hiding the truth and hiding points of improvement, for these TODO’s and FIXME’s are fixed in the end. And even if they get rid of all the TODO’s and FIXME’s before they release any of it they waste a lot of time it could have been used already (less efficiently though.. but it usualy doesn’t make such a big difference).&lt;/p&gt;</description></item><item><title>Services, a different approach</title><link>https://blog.affien.com/archives/2005/06/06/services-a-different-approach/</link><pubDate>Mon, 06 Jun 2005 20:38:17 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/06/services-a-different-approach/</guid><description>&lt;p&gt;A Server is a computer (or a group of them) that offers services.&lt;/p&gt;
&lt;p&gt;Such services could be a webmarket, a website, a game server and so on.&lt;/p&gt;
&lt;p&gt;These services tend all to be implemented quite differently, hardly interacting at all. All these services require a different approach, a different way to manage them. This creates both overhead and chaos.&lt;/p&gt;
&lt;p&gt;I`m working on a small framework intented to host services which is very flexible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework&lt;/strong&gt;&lt;br&gt;
A service isn’t a single process as it usualy is, although it could be put in its own seperate process. A service is rather just an instance of its servervice type in the framework somewhere, meaning you can have multiple instances of one service with different configurations scattered accross processes and even machines as you like.&lt;/p&gt;
&lt;p&gt;You can edit the settings and manage the services using the same API (and likely the same configuration tool).&lt;/p&gt;
&lt;p&gt;A service isn’t aware where it is hosted, from its perspective it is just in a framework with other services and service modules with which it can interact in always the same way.&lt;/p&gt;
&lt;p&gt;You as administrator however are aware of the services and its allocation. You can allocate a service (even runtime) to different locations which haven’t neccessarily got to be processes, but also can be lightweight processes found in .net like appdomains or on different machine’s processes.&lt;/p&gt;
&lt;p&gt;Having different processes for each service decreases performance but increases stability, and visa versa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interaction&lt;/strong&gt;&lt;br&gt;
Services shouldn’t be restricted to their own process but should also be able to interact with other services by using their exposed interfaces.&lt;/p&gt;
&lt;p&gt;An example could be a webserver-service which you provide with the name of the logger-service you want to be used for that webserver. The webserver could just interact by casting an object in the public interface dictionary of the logger to an log interface. The framework takes care of the required underlying communication like the remoting in case they are hosted on different processes or even different machines.&lt;/p&gt;
&lt;p&gt;A more tighter type of interaction would be modules. A module of a webserver could be a webmarker. The webmarket would just access the object of the webserver which handles hooking to certain URI, add the hooks and await a visit. Other services could do the same but a module is specificly bound to the service it attached to.&lt;/p&gt;
&lt;p&gt;Futhermore modules would be an easier way for administrators to manage extra functionality which is more module like than filling in the instance paths to use in the settings of a certain service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Portability&lt;/strong&gt;&lt;br&gt;
I`m still in doubt whether I should make it cross-language. It would be a good thing but it would certainly create havoc to make everything run smooth and alike on all languages. Not even to mention the overhead to load each languages’ runtime.&lt;/p&gt;</description></item><item><title>Power PC dumped</title><link>https://blog.affien.com/archives/2005/06/06/power-pc-dumped/</link><pubDate>Mon, 06 Jun 2005 07:12:57 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/06/power-pc-dumped/</guid><description>&lt;p&gt;&lt;a href="http://news.com.com/Apple+to+ditch+IBM%2C+switch+to+Intel+chips/2100-1006_3-5731398.html"&gt;Apple to ditch IBM, switch to Intel chips&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When Apple will switch to x86 and ia64 it will be possible to run mac osX on your own home bought computer, given that they don’t avoid it by changing some opcodes.&lt;/p&gt;
&lt;p&gt;One other things is sure; they will loose some power. As long as they provide binaries and provide one set for all apple computers they will have to add support for both ppc and x86 in one binary distribution which will undoubtely be a lot bigger if not slower too.&lt;/p&gt;
&lt;p&gt;It will be interesting to see how this issue will evolve.&lt;/p&gt;</description></item><item><title>Subversion</title><link>https://blog.affien.com/archives/2005/06/04/subversion/</link><pubDate>Sat, 04 Jun 2005 23:41:38 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/04/subversion/</guid><description>&lt;p&gt;I’ve recently been using CVS a lot, more specificly &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt;. It makes it &lt;em&gt;a lot&lt;/em&gt; easier to share source code. Where it wasn’t possible to work on the same projects or even on another project that depends on the first because sharing source code is tricky, subversion was the solution.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;mount..?&lt;/em&gt;&lt;br&gt;
As far as I know there isn’t a program that allows you to &lt;em&gt;mount&lt;/em&gt; a subversion repositry into the linux filesystem. This would make managing a subversion reposity a bit easier for at the moment you need to use &lt;code&gt;svn add&lt;/code&gt; to add every single file; &lt;code&gt;svn cp&lt;/code&gt; to copy, &lt;code&gt;svn rm&lt;/code&gt; to remove, and so on which could all be intergrated when wrapping a repositry up.&lt;/p&gt;
&lt;p&gt;It is possible I haven’t been searching in the right place. Searching for it just gave me an enourmous list of other people graving for it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;pruning&lt;/em&gt;&lt;br&gt;
To my knowladge there is no really easy way to get rid of older versions. Offcourse it would be against the basic idea behind the system storing every single version, but sometimes it just isn’t practicly. In case you are dealing with extra not sourcecode files, like images or data files, which usualy are quite large in comparison with source code, you’ll get a really big and slow repositry.&lt;/p&gt;
&lt;p&gt;Adding a feature that will &lt;em&gt;store&lt;/em&gt; all files before version &lt;em&gt;x&lt;/em&gt; if it isn’t the top version in a compressed archive of some type would be really nice. Although it would drasticly decrease the access time for the older versions it does decrease the space used and increases the access time for the top versions which are used a lot more than the older ones.&lt;/p&gt;</description></item><item><title>Opeth Ghost Reveries tour</title><link>https://blog.affien.com/archives/2005/06/04/opeth-ghost-reveries-tour/</link><pubDate>Sat, 04 Jun 2005 23:24:10 +0100</pubDate><guid>https://blog.affien.com/archives/2005/06/04/opeth-ghost-reveries-tour/</guid><description>&lt;p&gt;I just bought a ticket for an &lt;a href="http://opeth.com"&gt;Opeth&lt;/a&gt; performance in the Netherlands (&lt;a href="http://www.013web.nl/"&gt;013&lt;/a&gt;, Tilburg) on 11 september 2005. I’m looking forward to the performance even more, for Opeth really seems to be a great live band. I just bought their &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/B000127ZEG/ref=pd_sxp_f/002-4364134-8731263?v=glance&amp;amp;s=dvd"&gt;Lamentations DVD&lt;/a&gt;, which was quite amazing.&lt;/p&gt;</description></item><item><title>XBox 360</title><link>https://blog.affien.com/archives/2005/05/20/xbox-360/</link><pubDate>Fri, 20 May 2005 19:55:12 +0100</pubDate><guid>https://blog.affien.com/archives/2005/05/20/xbox-360/</guid><description>&lt;p&gt;Microsoft released the specifications of the XBox 360..&lt;br&gt;
it is a beast..&lt;/p&gt;
&lt;p&gt;With 3 CPU cores running on 3.2Ghz each with 2 hardware threads and 1 mb l2-cache each it is a powerhouse.&lt;/p&gt;
&lt;p&gt;A remarkable feature of the XBox 360 is that it has got processor level support for &lt;strong&gt;MSIL&lt;/strong&gt; (the bytecode used by .net applications).&lt;/p&gt;
&lt;p&gt;The best thing of the XBox 360 is that it’ll be quite cheap (~150$), this probably lets the XBox360 deliver the most processor capability per dollar.&lt;/p&gt;
&lt;p&gt;Maybe I’ll buy a few and make my own little linux server cluster with it, when the guys behind &lt;a href="http://www.xbox-linux.org/"&gt;xbox-linux.org&lt;/a&gt; have added support for the XBox360 :-).&lt;/p&gt;</description></item><item><title>Music Fill Out Thingy</title><link>https://blog.affien.com/archives/2005/05/19/music-fill-out-thingy/</link><pubDate>Thu, 19 May 2005 14:47:54 +0100</pubDate><guid>https://blog.affien.com/archives/2005/05/19/music-fill-out-thingy/</guid><description>&lt;p&gt;&lt;a href="http://www.zefhemel.com/archives/2005/05/19/hitting-it-with-a-music-baton"&gt;Zef handed&lt;/a&gt; me the music baton, meaning I got to fill out a form ’bout music. So well… here it is:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total volume of music files on my computer&lt;/strong&gt;&lt;br&gt;
3.2 GB.. that isn’t a lot.. but in contrary to some with huge collections I do listen to them all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The last CD I bought was&lt;/strong&gt;&lt;br&gt;
I got myself some albums of Children of Bodom recently. I`m trying to get the Lamentations DVD of Opeth.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Song playing right now&lt;/strong&gt;&lt;br&gt;
Opeth – Still Life – The Moor&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Five songs I listen to a lot/mean a lot to me&lt;/strong&gt;&lt;br&gt;
I don’t really listen to a certain song a lot.. although recently I listened to these a bit more than the others:&lt;/p&gt;
&lt;p&gt;– Opeth – The Drapery Falls&lt;br&gt;
– Children of Bodom – Needled 24/7&lt;br&gt;
– Nirvana – You Know You’re Right&lt;br&gt;
– Opeth – Dirge for November&lt;br&gt;
– Muse – Citizen Erased&lt;/p&gt;
&lt;p&gt;Lets be creative and add another question:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Artists you like&lt;/strong&gt;&lt;br&gt;
Opeth, Children of Bodom, Nightwish, Nirvana, Linkin Park and last but not least Muse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The five people where this meme will go on&lt;/strong&gt;&lt;br&gt;
– &lt;a href="http://www.entertheunknown.net/"&gt;Kaja Fumei&lt;/a&gt;&lt;br&gt;
– Noud Aldenhoven&lt;br&gt;
– &lt;a href="http://gumuz.looze.net/wordpress/"&gt;Gumuz&lt;/a&gt;&lt;br&gt;
– you!&lt;br&gt;
– (yes, i was out of idea`s)&lt;/p&gt;</description></item><item><title>Safe web authentication</title><link>https://blog.affien.com/archives/2005/05/16/safe-web-authentication/</link><pubDate>Mon, 16 May 2005 15:52:55 +0100</pubDate><guid>https://blog.affien.com/archives/2005/05/16/safe-web-authentication/</guid><description>&lt;p&gt;The major problem with security of web applications is that the client sends the login name and password in plain text if https isn’t available. A nasty person with access to the network could use ARP poisening alongside packet sniffing to acquire the login, which wouldn’t really be desirable.&lt;/p&gt;
&lt;p&gt;I stumbled accross a very interesting piece javascript which implements the md5 hash algorithm: &lt;a href="http://pajhome.org.uk/crypt/md5/"&gt;http://pajhome.org.uk/crypt/md5/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Using a hash makes it impossible to reverse engineer a password and makes authentication safer. An issue with this is that you only require the hash, not the password to get in. To prevent this the password should be salted before hashed.&lt;/p&gt;
&lt;p&gt;Basicly a secure authentication via http would look like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client sends&lt;/strong&gt; request for login to server.&lt;br&gt;
&lt;strong&gt;Server sends&lt;/strong&gt; the login form which includes a &lt;em&gt;login id&lt;/em&gt; and &lt;em&gt;salt&lt;/em&gt; to the client.&lt;br&gt;
&lt;strong&gt;Server stores&lt;/strong&gt; the &lt;em&gt;login id&lt;/em&gt; and &lt;em&gt;salt&lt;/em&gt; it sent to the client.&lt;br&gt;
&lt;strong&gt;Client sends&lt;/strong&gt; the &lt;em&gt;hash&lt;/em&gt; of the filled out password and received hash alongside the &lt;em&gt;login id&lt;/em&gt; from the server to the server.&lt;br&gt;
&lt;strong&gt;Server checks&lt;/strong&gt; whether the hash of the password in the database and the received hash combined with the login id are valid.&lt;br&gt;
&lt;strong&gt;Server sends&lt;/strong&gt; whether authentication was a success.&lt;/p&gt;
&lt;p&gt;Maybe I’ll implement an example application :-). In any case I hope that this will be employed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update, most authentication system used by webbased software are still vulnerable and would almost neglect the use of this by being able to hijack a session by just getting the session key. The client however could also implement javascript to use a similar method with a salt to protect the session key. The problem still is that it is extra overhead on the client and that not every client has got javascript enabled.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Assembly ‘programmers’ suck</title><link>https://blog.affien.com/archives/2005/05/14/assembly-programmers-suck/</link><pubDate>Sat, 14 May 2005 21:49:28 +0100</pubDate><guid>https://blog.affien.com/archives/2005/05/14/assembly-programmers-suck/</guid><description>&lt;p&gt;Some programmers claim writing assembly is the solution to every single programming issue, for it would be great for being down to the basics, or it creates small programs, or even be fast. For all I care they are just trying to brag for not a lot of people know how to program in assembly and it is generally seen as difficult to do.&lt;/p&gt;
&lt;p&gt;Programming in assembly is almost everytime a bad idea.&lt;/p&gt;
&lt;p&gt;So first, what exactly is assembly?&lt;br&gt;
Assembly is a text language with which you can write opcodes and arguments of machine code processed by the processor by hand. This gives you a very high amount of control of what the processor does. Whereas higher languages generate the machine code for you as they deem it to fit you can choose which machine code would fit.&lt;/p&gt;
&lt;p&gt;Assembly isn’t difficult to learn. Assembly is very straight forward. It just is hard to program for you don’t have functions, you don’t have high level structures, you don’t have all the aid of a high level languages.&lt;/p&gt;
&lt;p&gt;The reason programmers claim that assembly is superior is for with assembly you can write faster and smaller code. This is only partially true.&lt;/p&gt;
&lt;p&gt;When you know all opcodes and tricks you can pull on all different architectures you can beat a compiler.. The problem here is that there are tens of architectures with totally different opcodes and even more subarchitectures with each a slightly different implementation and different performance characteristics of each opcode or way to do something.&lt;/p&gt;
&lt;p&gt;So to truely beat a compiler which compiles one piece of code to assembly, you have to create for each different architecture a seperate piece of assembly source.&lt;/p&gt;
&lt;p&gt;You’d also have to learn all the opcodes of one cpu, that aren’t just a few hundred which would suffice to get it working, but thousands which are required to get it working as fast as possible.&lt;/p&gt;
&lt;p&gt;Compilers know all these extra opcodes and tricks for each architecture and would therefore a higher level programmer would do a better job on creating an executable than an experienced assembly programmer in the same amount of time. If the assembly programmer would want to beat the higher level programmer he would require not just 2 times more time but at least 10 times.&lt;/p&gt;
&lt;p&gt;Also assembly isn’t very portable. If you want to change one little thing you got to change it for all optimalizations for all different processors. I haven’t seen a big application written in assembly. And that has got a reason.&lt;/p&gt;
&lt;p&gt;Most programmers that claim to be able to write quick assembly don’t have got an idea how everything works exactly and are just thrilled that they made a little program work in assembly.&lt;/p&gt;
&lt;p&gt;Assembly though can be usefull. An example is an arbitrary length integer class like &lt;a href="http://www.swox.com/gmp"&gt;GMP&lt;/a&gt; which uses optimized assembly for certain operations. It aren’t a lot of operations done in assembly, but it certainly has got a lot of assembly. And it is worth it.&lt;/p&gt;
&lt;p&gt;Sticking with a good compiler and a high low level language like C is always the best option for good applications.&lt;/p&gt;</description></item><item><title>Gentoo Linux</title><link>https://blog.affien.com/archives/2005/05/06/gentoo-linux/</link><pubDate>Fri, 06 May 2005 22:06:52 +0100</pubDate><guid>https://blog.affien.com/archives/2005/05/06/gentoo-linux/</guid><description>&lt;p&gt;3 days ago I came accross &lt;a href="http://gentoo.org"&gt;gentoo linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Gentoo Linux is a linux redist that provides you with a livecd from which you are able to build a whole new linux installation practicly from scratch.&lt;/p&gt;
&lt;p&gt;Yes, that means compiling everything yourself.&lt;/p&gt;
&lt;p&gt;Normally compiling means reading through tons of documentation, trying to find dependencies, trying to get stuff working, making tweaks, and reading again through tons of documentation, trying to find dependencies, hoping version won’t collide, and again, and again.&lt;/p&gt;
&lt;p&gt;Luckily gentoo provides a very neat tool called &lt;em&gt;portage&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Portage allows you to simply install for instance gnome by just typing:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;emerge gnome&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Portage will look up which dependencies are required, download them, configure them, compile them, and clean up garbage. The only thing you got to do is hang back and relax.&lt;/p&gt;
&lt;p&gt;Portage also automaticly implements your preferenced optimalization settings to create the best possible build for every single application you compile.&lt;/p&gt;
&lt;p&gt;Gentoo seems to have resulted in a lot faster linux installation, although there is one little issue, it takes time.. A lot of time…&lt;/p&gt;
&lt;p&gt;Compiling gnome (with all dependencies) took about 8 hours…&lt;/p&gt;
&lt;p&gt;Maybe gentoo will be the first linux to kick windows from my desktop :-).&lt;/p&gt;</description></item><item><title>Extending using Wrapping</title><link>https://blog.affien.com/archives/2005/04/30/extending-using-wrapping/</link><pubDate>Sat, 30 Apr 2005 01:11:02 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/30/extending-using-wrapping/</guid><description>&lt;p&gt;Ever had a problem, not being able to add more functionality to an existing class? Some languages seem to support adding functionality to an existing class but it does make it less secure and leaves a lot of dangers of maluse.&lt;/p&gt;
&lt;p&gt;A solution could be to create a new class which &lt;em&gt;inherits&lt;/em&gt; the original class although it can only be instanciated using a cast from an instance of the original class or instanciating providing the original instance. Also it won’t be able to override anything otherwise it couldn’t act as its base object.&lt;/p&gt;
&lt;p&gt;A possible implementation of this idea could be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wrapper Int_IsOdd : int {
 public bool IsOdd() {
 return this % 2;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;And it could be used in several ways:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int myInt = 100;
print ((Int_IsOdd)myInt).IsOdd();
print myInt.IsOdd();
print new Int_IsOdd(myInt).IsOdd();
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The first way would be the easiest for both a reader which isn’t familiar with the extension and for the compiler to guess errors. The second would be neat to use but it would be confusing for people that cannot access the rest of the source or do not know what function is meant. The third way would be very compatible.&lt;/p&gt;
&lt;p&gt;I wondered by myself whether normal inheritance could provide this functionality.. and it does. The only problem is that polyforism only works up and not down as the wrapper requires. (when you got &lt;code&gt;a&lt;/code&gt; class &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; inherits of &lt;code&gt;a&lt;/code&gt;, you can with inheritance treat an instance of &lt;code&gt;b&lt;/code&gt; as &lt;code&gt;a&lt;/code&gt; but you cant treat an instance of &lt;code&gt;a&lt;/code&gt; as &lt;code&gt;b&lt;/code&gt; which is required for the wrapper)&lt;/p&gt;
&lt;p&gt;Also a wrapper would be more cached and not really a new instance as suggested by the way it seems to work and can already be slightly implemented in existing languages.&lt;/p&gt;
&lt;p&gt;Maybe it’ll be put in paradox.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;update – I talked with Kaja, and it will most likely be a feature of paradox&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>It’s all about the model</title><link>https://blog.affien.com/archives/2005/04/23/its-all-about-the-model/</link><pubDate>Sat, 23 Apr 2005 20:23:21 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/23/its-all-about-the-model/</guid><description>&lt;p&gt;With all those strange new physics theories and models which seem to conflict eachother it seems all rather too awquard to be true.&lt;/p&gt;
&lt;p&gt;Like Quantum Mechanics stating that something can be two things at the same time, which seems impossible, but certainly is when keeping in mind that Quantum Mechanics states that something is what it seems to be when measured where measurement always has to interact which means that very unstable states of an object don’t &lt;em&gt;exist&lt;/em&gt; but still can be applied on an object being two states at the same time with a third set of properties… great…&lt;/p&gt;
&lt;p&gt;What people don’t seem to realize is that most physics theories apparently conflict for they are formulated rather awquard, but only formulated like that for then they are reasonably understandable as a model. Also one given theory isn’t superior above another, usualy one theory just stresses a certain part of apparent reality more by the way it represents everything.&lt;/p&gt;
&lt;p&gt;There just isn’t the theory that explains how the universe works, there are only models covering a part in a certain way.&lt;/p&gt;
&lt;p&gt;I don’t care if someone likes to represents an atom as a little UFO, as long as the conclusions and predictions in that theory are usefull in being able to predict behaviour and characteristics.&lt;/p&gt;
&lt;p&gt;This is also where philosophie makes a fatal mistake, a philosopher would tend to use metaphores, scientificly called models, literaly assuming that reality is just a metaphore. And there ishardly anything you can do to persue them otherwise anyways :-).&lt;/p&gt;
&lt;p&gt;Apparently it seems, assuming the string theory is an accurate model, that we only experience an infinite small amount of the whole universe. It maybe could be seen that we are just a little (end) fractal in a big fractal (inside another).&lt;/p&gt;
&lt;p&gt;But why are we as we are? It would be logical to assume that we are nothing more than a logical result of one chaos like formula for the whole universe seems to be pseude randomly as many chaos formula’s seem. We’re just one of the infinite possibilities (stressing possibilities).&lt;/p&gt;
&lt;p&gt;That would seem rather depressing and our lives would seem rather useless.. and actually.. they are rather useless for the whole static everything. But actually that makes just one more reason to maintain our human species for otherwise we couldn’t enjoy our uselessness :-).&lt;/p&gt;
&lt;p&gt;And even if we would have to formula to predict everything (which maybe even has been found already by some mathematician, but is only experienced differently by us as models differ from eachother), we would only be interested in derived models for our perception of it to aid our uselessness :-).&lt;/p&gt;</description></item><item><title>Fun with hex</title><link>https://blog.affien.com/archives/2005/04/22/fun-with-hex/</link><pubDate>Fri, 22 Apr 2005 22:50:02 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/22/fun-with-hex/</guid><description>&lt;p&gt;&lt;a href="http://blog.w-nz.com/uploads/opethlogo1hb.jpg"&gt;&lt;img src="http://blog.w-nz.com/uploads/opethlogo1hb.jpg" alt="hexopeth"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yes, I was bored.&lt;/p&gt;
&lt;p&gt;(and no, I did not do that by hand)&lt;/p&gt;</description></item><item><title>Linux style</title><link>https://blog.affien.com/archives/2005/04/20/linux-style/</link><pubDate>Wed, 20 Apr 2005 15:57:35 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/20/linux-style/</guid><description>&lt;p&gt;Make your own tux toy:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://free-penguin.org/"&gt;&lt;img src="http://www.free-penguin.org/images/theTUX.jpg" alt="tux"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;They only redistribute source branches ^_^&lt;/p&gt;
&lt;p&gt;You got to config and build it manually..&lt;/p&gt;</description></item><item><title>Foolish people</title><link>https://blog.affien.com/archives/2005/04/19/foolish-people/</link><pubDate>Tue, 19 Apr 2005 21:44:48 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/19/foolish-people/</guid><description>&lt;p&gt;You can &lt;a href="http://www.ige.com/games.aspx?CatId=247&amp;amp;lang=en"&gt;buy World of Warcraft gold and items&lt;/a&gt; by paying &lt;strong&gt;real&lt;/strong&gt; money…&lt;/p&gt;
&lt;p&gt;It actually seems they are having quite good bussiness for the amount of adds linking to them has increased IMHO.&lt;/p&gt;
&lt;p&gt;So.. there must be a lot of people &lt;strong&gt;buying&lt;/strong&gt; basicly &lt;strong&gt;nothing&lt;/strong&gt; for damned high prices…&lt;/p&gt;
&lt;p&gt;How can people be so foolish?&lt;/p&gt;</description></item><item><title>Pope</title><link>https://blog.affien.com/archives/2005/04/19/pope/</link><pubDate>Tue, 19 Apr 2005 21:37:32 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/19/pope/</guid><description>&lt;p&gt;(dutch joke)&lt;/p&gt;
&lt;p&gt;Our brand new german pope: “Bedankt voor de stranden”&lt;/p&gt;</description></item><item><title>Note on logo</title><link>https://blog.affien.com/archives/2005/04/15/note-on-logo/</link><pubDate>Fri, 15 Apr 2005 23:42:52 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/15/note-on-logo/</guid><description>&lt;p&gt;I found some time to change the default logo of the wordpress theme to something I liked a bit more. I guess I`ll have to do a better layout for the website once but it takes too damned much time.&lt;/p&gt;
&lt;p&gt;Anyways, I was required to change both the CSS as obviously the Image, so &lt;strong&gt;press refresh&lt;/strong&gt; a few times if it doesn’t show up properly.&lt;/p&gt;
&lt;p&gt;(the logo itself is a part of a ‘o’, yeah.. the letter ‘o’… of the word opeth.. that opeth:&lt;br&gt;
&lt;img src="http://w-nz.com/images/opeth-logo1.jpg" alt="opeth logo"&gt;)&lt;/p&gt;</description></item><item><title>The Linux Paradox</title><link>https://blog.affien.com/archives/2005/04/15/the-linux-paradox/</link><pubDate>Fri, 15 Apr 2005 20:58:00 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/15/the-linux-paradox/</guid><description>&lt;p&gt;Linux wants to get popular. Everyone using linux wants linux to grow bigger and bigger to ultimately have linux be the operating system dominating. err.. correction.. independant distributions and inheritances of linux to avoid the nasty monopoly stuff. Even your mom should start using it.&lt;/p&gt;
&lt;p&gt;Sounds good. Even if linux is in some people`s opinion not the best OS it still has the best community backing it and is the most secure OS. It also has got the most support from the community. If something is required or has to be fixed it`ll happen in notime.&lt;/p&gt;
&lt;p&gt;So why doesn’t everyone use it already?&lt;/p&gt;
&lt;p&gt;The problem is that linux demands too much from the user.&lt;/p&gt;
&lt;p&gt;A linux user should be able to at least have a grip of how a console works. And preferably has to know how to compile application and fix bugs when it won’t compile. And a user should know how to get dependencies it misses. An user should read through the fast different documentation of each application to even begin to hope to get it running easily. And an user should start over every time a new version is released.&lt;/p&gt;
&lt;p&gt;Sure, they got RPM’s and yumm which makes life a lot easier. But the yum repositries don’t contain everything. If you want some new stuff, or an application with a certain module installed you have to go dig into configuration files, master the console, read through documentation, compile, and offcourse check your version dependencies, etc.&lt;/p&gt;
&lt;p&gt;The average windows user like your mom doesn’t even know how drives work and certainly have never heard about the command line. It just wouldn’t work out. They got a lot of trouble even with just one or two options. When confronted with linux with hundreds of possible options and even stranger errors it just won’t work out well between them.&lt;/p&gt;
&lt;p&gt;It certainly is possible to stick to the main applications provided by your redistribution and using the yum repositry. But linux will never run as satisfying as when you get it all compiled yourself and configured yourself. This really makes a big difference! I made linux start up a lot faster by compiling the kernel with only the modules I require with computer specific optimalizations. These little things give linux a really big edge over windows.&lt;/p&gt;
&lt;p&gt;Linux is and remains only interested for adventerous ‘power’ users with quite some free time on their hands.&lt;/p&gt;</description></item><item><title>Don’t rely on parsing</title><link>https://blog.affien.com/archives/2005/04/13/dont-rely-on-parsing/</link><pubDate>Wed, 13 Apr 2005 22:09:47 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/13/dont-rely-on-parsing/</guid><description>&lt;p&gt;Most applications store their settings (espacially in *nix) in text configuration files. These text files need to be parsed every time the application starts.&lt;/p&gt;
&lt;p&gt;Parsing is the action of (usualy streaming) dividing a certain piece of data into understandable parts. This usualy comes down to looking at the text file character by character and deciding what should be done. Usualy this is done by maintaining a state which contains the data collected sofar. And with a bit more complicated files this even means having a stack of states and complicated actions when a certain state is left.&lt;/p&gt;
&lt;p&gt;The problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parsing is slow, &lt;em&gt;very slow&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Formats required to be parsed contain overhead, &lt;em&gt;a lot of overhead&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But it certainly has got advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Humans can easily edit it, you don’t need to rely on configuration tools&lt;/li&gt;
&lt;li&gt;(Usualy) makes a configuration format more extensible by nature (adding one new field in the average programmer’s binary format would break it)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, there are attempts to help improve speed. This by standardizing the format, which makes the amount of oddities to expect less, which ultimately makes the whole parsing slightly faster. This at cost of the easiness it can be edited.&lt;/p&gt;
&lt;p&gt;A good example would be Xml. Xml is damned ugly. Xml is too strict. And &lt;em&gt;Xml still takes a hell of a lot of time to parse&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.yaml.org/"&gt;Yaml&lt;/a&gt; looked like a decent alternative: easy to edit, looks nice. But then I encountered this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;%YAML 1.1&lt;br/&gt;
---&lt;br/&gt;
!!map {&lt;br/&gt;
? !!str &amp;quot;sequence&amp;quot;&lt;br/&gt;
: !!seq [&lt;br/&gt;
!!str &amp;quot;one&amp;quot;, !!str &amp;quot;two&amp;quot;&lt;br/&gt;
],&lt;br/&gt;
? !!str &amp;quot;mapping&amp;quot;&lt;br/&gt;
: !!map {&lt;br/&gt;
? !!str &amp;quot;sky&amp;quot; : !!str &amp;quot;blue&amp;quot;,&lt;br/&gt;
? !!str &amp;quot;sea&amp;quot; : !!str &amp;quot;green&amp;quot;,&lt;br/&gt;
}&lt;br/&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ugly…&lt;/p&gt;
&lt;p&gt;So what to use instead?&lt;/p&gt;
&lt;p&gt;Use binary configuration files, which are easy to load and save for the application. And create a parser to parse the configuration file and save it to the binary format! In other words: serialize the usefull data from the parsed document and only parse again when it is required.&lt;/p&gt;
&lt;p&gt;When you only parse stuff when it has changed by the user than it doesn’t really matter how long it takes to parse. Which can get rid of the really ugly stuff and let us just have a very loose kind of format without the ugly rules and regulations.&lt;/p&gt;</description></item><item><title>‘Objects’ in C – Part 3</title><link>https://blog.affien.com/archives/2005/04/05/objects-in-c-part-3/</link><pubDate>Tue, 05 Apr 2005 20:36:15 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/05/objects-in-c-part-3/</guid><description>&lt;p&gt;In Part 3 of this mini serie I`ll discuss how interfaces / (multi)inheritance like behaviour can be achieved in a language like C as in C++.&lt;/p&gt;
&lt;p&gt;In the posts before (&lt;a href="http://blog.w-nz.com/archives/2004/12/14/objects-in-c/"&gt;part 1&lt;/a&gt;, &lt;a href="http://blog.w-nz.com/archives/2004/12/15/objects-in-c-2/"&gt;part 2&lt;/a&gt;) I discussed the possibility to inherit behaviour of an ‘object’ in C by adding a type pointer which handles initialization and destruction of the object; achieving the possibility to extend an ‘object’ by adding fields at the end and updating the type pointer to a new type.&lt;/p&gt;
&lt;p&gt;Any object contains a pointer at the start to its &lt;em&gt;type&lt;/em&gt;. The type of an object is passed to the &lt;code&gt;CreateInstance&lt;/code&gt; function when an instance needs to be created of the object. The type itself just contains a few fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Length&lt;/strong&gt;, the required length of the object, this allows an inheritance to extend the amount of data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Constructor Function Pointer&lt;/strong&gt;, the Constructor Function Pointer is called after the object is allocated to construct its contents.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Destructor Function Pointer&lt;/strong&gt;, the Destructor Function Pointer is called before the object is freed to destruct its contents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These fields, along with using function pointers in the instance itself instead of functions, allow an inherited type to expand the existing type. The problem is that an object can’t inherit from more than one object, for both object’s expect to start just after the pointer to the type. To solve this an additional field needs to be added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;QueryInterface Function Pointer&lt;/strong&gt;, the QueryInterface Function Pointer can be used to get an instance of a supported type from the instance called.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top Object Pointer&lt;/strong&gt;, the Top pointer points to the top object. (An object returned from QueryInterface its Top pointer would point to the object where QueryInterface was called)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;nb. The latter one will be added after the type pointer in the instance instead of in the type&lt;/p&gt;
&lt;p&gt;A good example would be a type called &lt;code&gt;ICloneable&lt;/code&gt; which itself only contains one field: Clone, a functionpointer to a function to clone the object. When you would want to clone an object given you would use:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ICloneable* interface = toClone-&amp;gt;top-&amp;gt;type-&amp;gt;QueryInterface(toClone-&amp;gt;top-&amp;gt;type, toClone-&amp;gt;top, ICloneableType);&lt;br/&gt;
Object* clone = interface-&amp;gt;Clone(interface);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Lets take a look to the first line:&lt;br&gt;
&lt;code&gt;ICloneable* interface = toClone-&amp;gt;top-&amp;gt;type-&amp;gt;QueryInterface(toClone-&amp;gt;top-&amp;gt;type, toClone-&amp;gt;top, ICloneableType);&lt;/code&gt;&lt;br&gt;
This line queries the interface that the object that will be cloned wants you to use to clone it. The top object is used for that is the only way to be certain that you are dealing with the top object and the latest code instead of some base. Using this code an object can be cloned by just providing its interface!&lt;/p&gt;
&lt;p&gt;(the QueryInterface takes 3 parameters: first one is the type itself where the function pointer relies, second is the object in question, third is the requested type where ICloneableType is an instance of the ICloneable type).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Object* clone = interface-&amp;gt;Clone(interface);&lt;/code&gt;&lt;br&gt;
The second line just calls the functionpointer in the interface queried.&lt;/p&gt;
&lt;p&gt;To ensure that every bit of behaviour can be overriden, the object queried using &lt;code&gt;-&amp;gt;top-&amp;gt;type-&amp;gt;QueryInterface&lt;/code&gt; on the provided object must be used instead of the provided object itself for the provided object can be a whole different object merely supporting that interface secondarily.&lt;/p&gt;
&lt;p&gt;The nice thing about this architecture is that a top object merely wraps its implemented objects and returns them (possibly addapted) when queried for it. This allows way more access to the inherited types than in any other object orientated model.&lt;/p&gt;
&lt;p&gt;This model is quite easy to implement in C and (I hope) will be easy to intergrate with for instance objects in a Virtual Machine.&lt;/p&gt;</description></item><item><title>How to GC in C(++)</title><link>https://blog.affien.com/archives/2005/04/03/how-to-gc-in-c/</link><pubDate>Sun, 03 Apr 2005 22:51:04 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/03/how-to-gc-in-c/</guid><description>&lt;p&gt;GC`s, Garbage Collectors, are systems to manage memory. Even the good-old C-runtime library has its GC. &lt;code&gt;free&lt;/code&gt;, &lt;code&gt;malloc&lt;/code&gt; and the others. Now, these aren’t the best memory managers there are. They cause fragmented memory, and scatter the memory of your application over the whole memory rendering the great &lt;em&gt;processor l1 and l2 cache&lt;/em&gt; almost useless.&lt;/p&gt;
&lt;p&gt;I won’t talk about how to use the &lt;em&gt;C ‘GC’&lt;/em&gt;, but how to implement new-generation alike Garbage Collectors in C(++).&lt;/p&gt;
&lt;p&gt;The best GC`s can be found in Intermediate Language Virtual Machines which keep track of every object`s type in the memory and can therefore freely move objects in the memory. The great advantage of this is that object that have survived about as much Garbage Collects tend to link a lot to eachother and use eachother. That group survivors is called a generation. When you put a generation close to eachother in the memory, it will usualy only take 1 RAM memory load for the CPU, caching the whole generation in the CPU cache, for a while which is a lot quicker considering that l2-cache is about a thousand times faster than normal RAM.&lt;/p&gt;
&lt;p&gt;The problem in C(++) is that you can’t just move objects. You don’t know what part of the memory of an object is a pointer, and what is just a mere integer. Therefore it is impossible to make a generation based Garbage Collector for you just can’t move stuff.&lt;/p&gt;
&lt;p&gt;Allocating a big chunks and putting the objects of the C(++) application however using a custom allocation function will generate some additional performance above the traditional &lt;code&gt;malloc&lt;/code&gt; although it still isn’t perfect.&lt;/p&gt;
&lt;p&gt;One way to get it to work is to &lt;strong&gt;let the GC know what a pointer is and what now&lt;/strong&gt;. This can be done by letting the first 4 (or 8 bytes in case of a 64bit CPU) be a pointer to a function which returns an array of offsets which resemble the pointers in the type.&lt;/p&gt;
&lt;p&gt;Now the GC knows what the pointers are in a structure :-D.&lt;/p&gt;
&lt;p&gt;The GC can now move the object by updating the pointers from the other objects to the new location of the object!&lt;/p&gt;
&lt;p&gt;The only problem with this is that there &lt;strong&gt;can’t be pointers to the object, or inside the object from a not referenced pointer exposing object or a object that doesn’t exposes it pointers at all&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To overcome this I guess it could be feasable to add a flag byte in each object that exposes it pointers which allows it to specify a function that can be called when moving the object or when an object referenced is moved.&lt;/p&gt;
&lt;p&gt;I’ve tried out some ways to get this all wrapped up in a nice framework (which is very feasable using my ‘&lt;a href="http://blog.w-nz.com/archives/2004/12/16/intrepid-c-objects-in-c/"&gt;objects in c&lt;/a&gt;-framework’ or something similar (easier) in C++ using inheritance).&lt;/p&gt;
&lt;p&gt;I`m afraid however that such a GC comes too late for by the time it is reliable the Intermediate Languages would have gained way more ground for these can implement way more optimalizations, including in the GC, during runtime for they tend to use an Ahead of Time and Just in Time compiler.&lt;/p&gt;
&lt;p&gt;Feedback on this would be welcome :-).&lt;/p&gt;</description></item><item><title>Softwire</title><link>https://blog.affien.com/archives/2005/04/02/softwire/</link><pubDate>Sat, 02 Apr 2005 23:43:25 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/02/softwire/</guid><description>&lt;p&gt;&lt;a href="http://softwire.sourceforge.net/"&gt;Softwire&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Softwire is a library to generate assembly runtime for different kind of processors. It has a great API. Very usefull for JIT alikes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://entertheunknown.net"&gt;Kaja&lt;/a&gt; is converting it for use in C for the &lt;a href="http://blog.w-nz.com/archives/2005/03/12/introducing-paradox/"&gt;Paradox JIT&lt;/a&gt;. Hopefully it’ll be a lot faster replacing virtual class function calls with macro’s.&lt;/p&gt;
&lt;p&gt;Great stuff to play with 🙂&lt;/p&gt;</description></item><item><title>April`s first</title><link>https://blog.affien.com/archives/2005/04/01/aprils-first/</link><pubDate>Fri, 01 Apr 2005 00:00:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/04/01/aprils-first/</guid><description>&lt;p&gt;&lt;em&gt;[Insert stupid joke here]&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Downtime</title><link>https://blog.affien.com/archives/2005/03/28/downtime/</link><pubDate>Mon, 28 Mar 2005 01:00:00 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/28/downtime/</guid><description>&lt;p&gt;Due to server upgrades taking a bit more time than expected there was a little bit too much downtime.. sorry about that.&lt;/p&gt;</description></item><item><title>PHPavascript</title><link>https://blog.affien.com/archives/2005/03/23/phpavascript/</link><pubDate>Wed, 23 Mar 2005 22:46:00 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/23/phpavascript/</guid><description>&lt;p&gt;Due to the recent hypes around Ajax and web development I’ve been thinking about a more effective method to write web applications running both on the server as on the client by writing code in just one environment and language instead of two: PHPavascript.&lt;/p&gt;
&lt;p&gt;Having all kinds of fancy libraries to help you does help a lot; but you still got to manage transfering all data from the client and the server and back by hand; which espacially with javascript is quite tricky to do not only because it isn’t the easiest language to debug but also because every browser tends to do things a bit different with javascript.&lt;/p&gt;
&lt;p&gt;It would be nice, I thought, to have a language for developing sererside and client side at the same time:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;client TextBox mytextbox = TextBox.FromId(&amp;#34;mytextbox&amp;#34;);

int server function CalculateSum(first, second) {
 return first + second;
}

void client function ShowSum(first, second) {
 mytextbox.text = CalculateSum(first, second);
}

ShowSum(10,1000);
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Basicly you mark a language entity to be either on the client or server side. The compiler would take care of the rest.&lt;/p&gt;
&lt;p&gt;This would be really cool if it would be implemented but there would be quite a few issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All client side functions and variables can be forged by the user; a naive programmer could put too much trust in functions on the client side&lt;/li&gt;
&lt;li&gt;Synchronizing variables on server and client side and executing functions on server and client side could with a suffisticated algorithm be managed pretty decently although it would still create a lot of overhead when the programmer doesn’t pay attention on the usage of his function/variable location. Having hundreds of variable transfers for one page would be a lot, although very possible when a programmer doesn’t take care or the compiler is too dumb.&lt;/li&gt;
&lt;li&gt;Language features available on the server side and only available on the client side with dirty hacks could be a bottleneck if the programmer doesnt take enough care. How to implement a mySQL connection for instance (not considering the fact that it wouldn’t be very safe in the first place)&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basicly it would be way easier to develop a web application but I don’t know what would be better: having a hard to handle situation as it is now where you are forced to think efficiently, or an easy to use environment as such a language could provide where everything works with the temptingness of not even thinking about what happens beneath the bonnet.&lt;/p&gt;
&lt;p&gt;Although there still are these advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vastly reduced development time&lt;/li&gt;
&lt;li&gt;Highly maintainable code; a compiler could even create seperate javascript files for each specific browser and compile to the desired server side language&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ajax, the hype</title><link>https://blog.affien.com/archives/2005/03/22/ajax-the-hype/</link><pubDate>Tue, 22 Mar 2005 17:37:51 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/22/ajax-the-hype/</guid><description>&lt;p&gt;It’s new!&lt;/p&gt;
&lt;p&gt;It’s cool!&lt;/p&gt;
&lt;p&gt;And now it even got a name! &lt;strong&gt;Ajax&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;(&lt;a href="http://www.adaptivepath.com/publications/essays/archives/000385.php"&gt;what’s ajax?&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The funny this is that it &lt;em&gt;is quite old&lt;/em&gt; and it has been &lt;em&gt;used for a long time&lt;/em&gt; already. It just wasn’t &lt;em&gt;hyped&lt;/em&gt; before.&lt;/p&gt;
&lt;p&gt;Also this phenomenon clearly illustrates the dissatisfaction with the current static Html document standard common to the world wide web. Don’t deny it: html sucks for user interfaces! Html is a format for &lt;em&gt;documents&lt;/em&gt; not&lt;em&gt;user interfaces&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A child of Html could make a nice User Interface definition; main thing would getting rid of awquard javascript. Using a more dynamic Document Object Model, and espacially a consistant one, with some kind of Intermediate Language providing power but still security like Java, or .Net or maybe a new one, which should be hosted by the browser itself instead of a nasty plugin noone has, would be perfect.&lt;/p&gt;</description></item><item><title>Phalanger</title><link>https://blog.affien.com/archives/2005/03/19/phalanger/</link><pubDate>Sat, 19 Mar 2005 11:44:46 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/19/phalanger/</guid><description>&lt;p&gt;&lt;a href="http://www.php-compiler.net/"&gt;Phalanger&lt;/a&gt; is a &lt;a href="http://php.net/"&gt;PHP&lt;/a&gt;-Compiler for the &lt;a href="http://msdn.microsoft.com/netframework/default.aspx"&gt;.net framework&lt;/a&gt;. It can be used to run existing PHP applications on asp.net webservers with far greater performance than using PHP itself:&lt;br&gt;
&lt;img src="http://blog.w-nz.com/uploads/BenchLuboss.gif" alt=""&gt;&lt;br&gt;
In contrary with PHP itself the bottleneck isn’t the execution of the code itself but the underlying functions for executing the code: phalanger still uses the PHP library for the PHP functions which creates a lot of overhead due to interop and makes the PHP objects not as native to .net as it could. In contrary to PHP you would be best off not using the functions but trying to use the .net ones or your own written.&lt;/p&gt;
&lt;p&gt;In my own little benchmark for basic differences between normal .net and PHP, PHP came out to be 5000 times slower. When phalanger finaly compiles into proper .net code by avoiding any PHP library and PHP interop it would be a -lot- faster. When people would start to like it and install &lt;a href="http://apacheworld.org/modmono/"&gt;mod_mono&lt;/a&gt; on their apache webservers to run it they would probably find that they’ll be better of with asp.net with c# or vb.net. They after all got a way cleaner syntax than PHP and are happier working with the .net framework. (I don’t want to know what hacks they used at the phalanger compiler to get &lt;code&gt;include&lt;/code&gt; and &lt;code&gt;require&lt;/code&gt; working when compiling everything to one dll).&lt;/p&gt;
&lt;p&gt;In the mean time &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=48906"&gt;microsoft is rubbing its hands&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Copy protecting</title><link>https://blog.affien.com/archives/2005/03/17/copy-protecting/</link><pubDate>Thu, 17 Mar 2005 19:15:19 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/17/copy-protecting/</guid><description>&lt;p&gt;From software, audio to video are being illegaly copied and everytime the major brands try to implement some kind of protection. They always claim their protection to be perfect, and yet it is always broken, for it is quite simple:&lt;/p&gt;
&lt;p&gt;As long as the intended user has the platform on which he`ll run it in his own possession he can always adapt it in someway to extract the data. Even the best video protection can’t beat making a bypass in your monitor to acquire the image on your screen.&lt;/p&gt;
&lt;p&gt;Even protecting something like a DVD is almost impossible. The dvd player hardware and software must be able to read what’s on the cd, and a protection must be able to be read to. Also there must be dvd writers to write a protection. Now all major brands can say they’ll put a protection in their DVD burners to protect from writing to the DVD protection section, but then another brand creates their DVD burners that can write to it and everyone will buy those which the big brands won’t let happen. And even if they got the disk itself truly protected someone can emulate the DVD using software or even hardware.&lt;/p&gt;
&lt;p&gt;Also there are things that allow itself to be copied, but the original copier can be tracked; this by putting in every video/song/software a unique signature which can be tracked back to the store which then can track it back to the person who copied it. Sounds great, would be impossible to forge when they use strong RSA like cryptography, just one problem, when inserting random trash instead of the signature someone can know the piece is illegal but cannot track someone, hopeless.&lt;/p&gt;
&lt;p&gt;The only, and only way, to stop illegal copying is making buying legaly less of an effort than acquiring illegaly. I hope they will relize this sooner or later for honoustly I`m becoming sick of all those ‘magic’ protections.&lt;/p&gt;</description></item><item><title>Enter The Unkown: Algorithm`s A programmer Has Got To Know</title><link>https://blog.affien.com/archives/2005/03/16/enter-the-unkown-algorithms-a-programmer-has-got-to-know/</link><pubDate>Wed, 16 Mar 2005 21:51:16 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/16/enter-the-unkown-algorithms-a-programmer-has-got-to-know/</guid><description>&lt;p&gt;I don’t like to link to other blogs or articles for I am just a lame copier, but I’d like to point my select few readers to &lt;a href="http://www.entertheunknown.net"&gt;Enter The Unkown&lt;/a&gt;, the weblog of Kaja Fumei, where he will point out some &lt;em&gt;Algorithms a Programmer should know&lt;/em&gt;. First one in the list are the &lt;a href="http://www.entertheunknown.net/?p=6"&gt;Hash Tables&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You don’t need to know the stuff behind these kind of features a language library exposes; but it helps a lot if you know how it works and what the weak and strong points are.&lt;/p&gt;</description></item><item><title>Easy Crossbrowser JavaScript</title><link>https://blog.affien.com/archives/2005/03/16/easy-crossbrowser-javascript/</link><pubDate>Wed, 16 Mar 2005 12:47:22 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/16/easy-crossbrowser-javascript/</guid><description>&lt;p&gt;The major problem when dealing with javascript for me was that javascript acts differently on each different browser. And there are a lot of browsers supporting javascript.&lt;br&gt;
Usualy to get it working it would include having for each sensitive operation a big &lt;code&gt;if&lt;/code&gt; block. And in the &lt;em&gt;a bit nicer&lt;/em&gt; javascripts that would become a lot. Also it becomes hard to maintain.&lt;/p&gt;
&lt;p&gt;So what to do about it?&lt;/p&gt;
&lt;p&gt;Actually.. C(++) gave me a possible solution. Use &lt;em&gt;macro`s&lt;/em&gt;. It ain’t possible to use macro`s in javascript itself feasable, so what you do is you compile your javascript with macro`s to a different javascript file for each browser. Then using a simple server side script you can let the browser get what it wants.&lt;/p&gt;
&lt;p&gt;I’m not a javascript guru, so I hardly know all the problems of each browser.&lt;/p&gt;
&lt;p&gt;If a javascript guru does read it, please contact me – it would be great to have such a goodie.&lt;/p&gt;</description></item><item><title>Introducing Paradox</title><link>https://blog.affien.com/archives/2005/03/12/introducing-paradox/</link><pubDate>Sat, 12 Mar 2005 19:53:18 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/12/introducing-paradox/</guid><description>&lt;p&gt;Kaja Fumei and I are currently developing a light-weight rich jit-ed language called &lt;em&gt;Paradox&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The main feature of Paradox will be that it will be very light weight in memory and startup time.&lt;/p&gt;
&lt;p&gt;It will be great to use for scripting in other applications which demand high performance like for instance games. Also for normal scripting purposes or normal applications it will be way more suitable than normal interpreted languages.&lt;/p&gt;
&lt;p&gt;Basicly it will feature a &lt;abbr title="Just In Time"&gt;JIT&lt;/abbr&gt; Compiler, Generation &lt;abbr title="Garbage Collector"&gt;GC&lt;/abbr&gt;, rich (modulair) base library and a being very extensible.&lt;/p&gt;
&lt;p&gt;It will probably not perform as good as the .net framework but will rather come in the range of mono`s and java`s performance, which is very high compared to the performance of normal scripts.&lt;/p&gt;
&lt;p&gt;When Kaja, who is currently working on the JITc and gGC finished the base I’ll start working on the core library and help optimizing and I will post a preview of its capabilities.&lt;/p&gt;
&lt;p&gt;(for those wondering how long it will take:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Unknown – æ£®ã®ä¸­ã«æœ¨ãŒãªã„ã€‚ says:&lt;br&gt;
reeally long week&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;)&lt;/p&gt;</description></item><item><title>Beating Spam</title><link>https://blog.affien.com/archives/2005/03/11/beating-spam/</link><pubDate>Fri, 11 Mar 2005 22:46:46 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/11/beating-spam/</guid><description>&lt;p&gt;Most mail clients now include spam filters, which are learning and improving themselves.&lt;/p&gt;
&lt;p&gt;The problem though is that when spam keeps getting smarter your program has got too which still means reporting half of your spam mail as spam and checking your spam mail for your regular mail. Also when you start again after a reinstall and the spam filter has lost its experience you got to start over again.&lt;/p&gt;
&lt;p&gt;Now, I guess it would be great to create a centralized independant organization specificly to regognize (and when it becomes successfull also extract the spammers for prosecution) spam.&lt;/p&gt;
&lt;p&gt;The problem is how to organize such a centralized system, for when someone receives a spam email it has got to check with the centralized server whether the spam is spam. The amounts of spam are huge and doubling the enourmous bandwidth and cpu spam has costed already isn’t a very pleasant foresight.&lt;/p&gt;
&lt;p&gt;It would be feasable however to create a spam regognition service to run on a clients computer which updates itself with the latest definitions once in a while. This would undoubtly be way more efficient.&lt;/p&gt;
&lt;p&gt;The only problem that we are left with is how to get such a system to be intergrated with existing applications, if no one uses it it would be rather useless.&lt;/p&gt;
&lt;p&gt;When you have some idea`s on this, please share them.&lt;/p&gt;</description></item><item><title>Trying Thunderbird</title><link>https://blog.affien.com/archives/2005/03/10/trying-thunderbird/</link><pubDate>Thu, 10 Mar 2005 22:53:09 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/10/trying-thunderbird/</guid><description>&lt;p&gt;When I got my windows reinstalled I tought it was time to try something else than Office Outlook (espacially because a big mailbox makes Outlook slow), so I tried out &lt;a href="http://www.mozilla.org/products/thunderbird/"&gt;Mozilla Thunderbird&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What I noticed about Thunderbird in comparison with Outlook:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Faster, slicker UI&lt;/strong&gt;&lt;br&gt;
Although Thunderbird doesn’t look as great as Outlook it certainly has got a nice interface which is customizable enough.&lt;br&gt;
The Interface itself is also a lot faster than Outlook`s, which I find more important than grafical splender.&lt;br&gt;
Also the collapsable headerview above emails and information bars above the email (eg. a bar showing that thunderbird thinks the email or spam or that thunderbird is blocking images) are a nice addition and are worked out better than in Outlook containing them in a limited way.&lt;br&gt;
Also thunderbird seems to interface directly with firefox letting it show html emails a lot faster than Outlook does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;br&gt;
In the beginning the configuration was rather confusing. Although this also applied to the configuration with Outlook when I first tried it out. I still think that the account configuration interface could have been a lot more intuitive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Outgoing mail&lt;/strong&gt;&lt;br&gt;
Thunderbird requires and actually uses only one smtp server for all your mail accounts. Although you can specify more it doesn’t seem to be able to specify which Smtp server to use to sent the actual mail. This is a shame for espacially when sending important emails it is more trustworthy if the email can be traced back to the smtp server of the original domain. Also some smtp servers don’t allow seemingly spoofed `from` fields.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extensions&lt;/strong&gt;&lt;br&gt;
Thunderbird seems to have a very similar extension system as Firefox which I can appreciate. There are some very usefull extensions like &lt;a href="http://enigmail.mozdev.org/"&gt;Enigmail&lt;/a&gt; which is a front end for &lt;a href="http://www.gnupg.org/"&gt;GPG&lt;/a&gt; for Assymetric email encryption. It doesn’t only manage your encrypted emails, it also got a very good interface for all kinds of GPG operations like all kinds of key managment.&lt;/p&gt;
&lt;p&gt;Everybody should give thunderbird a try, it’s a great toy :).&lt;/p&gt;</description></item><item><title>Plugins, the web and python</title><link>https://blog.affien.com/archives/2005/03/09/plugins-the-web-and-python/</link><pubDate>Wed, 09 Mar 2005 14:51:16 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/09/plugins-the-web-and-python/</guid><description>&lt;p&gt;Plugins for web applications seems to be discussed a lot more recently by bloggers (&lt;a href="http://zefhemel.com/"&gt;Zef did&lt;/a&gt; for instance).&lt;/p&gt;
&lt;p&gt;Plugins usualy come in 2 shapes: hacks and modules.&lt;/p&gt;
&lt;p&gt;The key difference between a hack and a module is that a hack changes existing behaviour and a module adds behaviour or maybe extends some. In &lt;a href="http://zefhemel.com/"&gt;Zef`s example&lt;/a&gt; he is talking about possibly adding a calander to &lt;a href="http://gmail.google.com/"&gt;google`s gmail&lt;/a&gt; – that is definitely a module.&lt;/p&gt;
&lt;p&gt;When changing the whole interface by for instance being able to plan appointments inside other module`s (like viewing email) that would require changing those modules and basicly make it a hack.&lt;/p&gt;
&lt;p&gt;Modules are easy to make and maintain for they form seperate entitites which don’t often conflict. Most web applications already support module-based plugins like &lt;a href="http://www.invisionboard.com"&gt;IPB&lt;/a&gt;. Some more functionality can be added to modules by letting modules hook onto certain events in the other application, but this has its limits.&lt;/p&gt;
&lt;p&gt;Where hacks are also widely used, although these are very hard to maintain and usualy conflict which eachother.&lt;/p&gt;
&lt;p&gt;So what is the best way to write a plugin based application?&lt;/p&gt;
&lt;p&gt;I was thinking about that when I was working on a computer version of the popular card game &lt;a href="http://www.wizards.com/magic/welcome.asp"&gt;Magic&lt;/a&gt;. There are already a lot of computer version which let players play the game but the players have to apply the rules themselves.. the computer doesn’t do that for them for there are for every card a lot of exceptions and new rules are added every month. To make such a game plugins would be required.&lt;/p&gt;
&lt;p&gt;The way I solved this is by putting everything in the game in modules/plugins. The only thing the game does is saying ‘start’ to all plugins. One plugin responds to that and that may for instance be the UI plugin which shows the main UI form and then sais ‘postgui-start’, where another plugin may respond that extends the UI form for some new features in the game and then calls ‘postseries4gui-start’. A card itself is represented by a big hashtable containing all info of that card dynamicly, including functions. Letting one create-card attack another basicly is just a big dynamicly getting properties and calling functions which all are overloaded for new rules which seems to work pretty fine.&lt;/p&gt;
&lt;p&gt;Guess what I used to develop this highly dynamic interaction which eachother?&lt;/p&gt;
&lt;p&gt;Python!&lt;/p&gt;
&lt;p&gt;Python is the perfect language for plugins.&lt;/p&gt;
&lt;p&gt;Now.. why don’t we already got really nice web applications allowing this kind of highly dynamic plugins? Web applications are although using sessions, primarily stateless.. On every page view the whole script is loaded in the memory, and executed again and then unloaded. Nothing keeps persistant. Using plugins generates a lot of overhead on espacially loading stuff for every plugin must be able to hook onto and interact with everything. Doing this with the current model webservers just don’t work.&lt;/p&gt;
&lt;p&gt;I already made some suggestions &lt;a href="http://blog.w-nz.com/archives/2004/12/11/modular-server/"&gt;how to solve this&lt;/a&gt; at the server side, but changing this would take a lot of time.&lt;/p&gt;
&lt;p&gt;So to get back to how to get this done -now- and not later is to keep working with a modulair way exposing the most used hooks and data access.&lt;/p&gt;
&lt;p&gt;A suggestion for gmail:&lt;/p&gt;
&lt;p&gt;Allow SOAP based access to gmail`s features. Exactly the same amount as access as the user has got.&lt;br&gt;
Then allow adding new menu items and hooks on which a call is made to your specified url, which then can work with gmail on the client-access level using SOAP calls.&lt;/p&gt;
&lt;p&gt;Best would be for google to just expose the api of gmail and give a limited functionality dev download so people can make modules in the source and send them to google back. If they like it they’ll use it.. I guess google will come up with something like that once. Or at least I hope it.&lt;/p&gt;</description></item><item><title>Dyslexia</title><link>https://blog.affien.com/archives/2005/03/09/dyslexia/</link><pubDate>Wed, 09 Mar 2005 14:19:48 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/09/dyslexia/</guid><description>&lt;p&gt;They just found out me (and my brother) are affected by Dyslexia. A &lt;em&gt;bit&lt;/em&gt; late. The strange thing is that I didn’t really notice it that much, it seems that not having motivation for all those foreign languages isn’t the only reason for those really bad marks.&lt;/p&gt;</description></item><item><title>selfish driver control panels</title><link>https://blog.affien.com/archives/2005/03/08/selfish-driver-control-panels/</link><pubDate>Tue, 08 Mar 2005 18:30:43 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/08/selfish-driver-control-panels/</guid><description>&lt;p&gt;A week ago my windows was agonizing slow. Starting up would take ages, and getting those ‘windows is out of virtual memory’ messages was common, so I decided to reinstall windows.&lt;br&gt;
When reinstalled windows was using 120 mb without anything special installed.. so I started to install my usual application: apache, mysql, mssql.net express, php.. etc..&lt;br&gt;
At the point I got those installed windows was using 250 mb instead of 120mb! msSQL server uses 50mb`s (although that number isn’t displayed in the task manager properly (i guess due to modules). MySQL and Apache both 25mb`s…&lt;br&gt;
So I put the apache/sql servers services off by default and made a little bat script to start those when I want and put that one on my desktop. I also made a backup of windows so I didn’t need that horribly slow reinstall..&lt;br&gt;
I installed some basic drivers via the provided driver cd’s loading a lot of junk like tray icons on my computer. They did not appear to use a lot of memory in the taskmanager but when quiting them it saved 100 mb :-/. 100mb used by selfish driver control panels thinking they are the single-most-used application and the only one sucking that amount of memory…&lt;br&gt;
So instead of using those horrible flashy flash autorun installers I let windows find the correct driver .inf files and install it.&lt;br&gt;
This really saves a lot of performance.. (I’ve cut down my startup time by 4 times).&lt;/p&gt;
&lt;p&gt;So, better let windows find the drivers you require on your driver cd’s instead of using those selfish flashy traybar spamming driver control panel installers.&lt;/p&gt;</description></item><item><title>Xr12 concept</title><link>https://blog.affien.com/archives/2005/03/07/xr12-concept/</link><pubDate>Mon, 07 Mar 2005 00:43:46 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/07/xr12-concept/</guid><description>&lt;p&gt;I’ve been wanting to develop a massive online browser based game for a long time, for I have been addicted to those for quite some time and have been missing a lot of features and user input.&lt;/p&gt;
&lt;p&gt;And here it is, I got myself already a few other people to help, and I just finished the server architecture for when it gets big:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/papers/xr12concept"&gt;Xr12 concept&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I just hope I`ll be able to affort the system due to user activity, from experience I’ve seen that these online games tend to grow really fast.&lt;/p&gt;</description></item><item><title>Python Html Document Abstraction</title><link>https://blog.affien.com/archives/2005/03/06/python-html-document-abstraction/</link><pubDate>Sun, 06 Mar 2005 19:15:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/06/python-html-document-abstraction/</guid><description>&lt;p&gt;Python is great!&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; d = document()
&amp;gt;&amp;gt;&amp;gt; d.html.body.h1.value = &amp;#34;My Site!&amp;#34;
&amp;gt;&amp;gt;&amp;gt; d.html.body.p.value = &amp;#34;Welcome to this python generated site&amp;#34;
&amp;gt;&amp;gt;&amp;gt; str(d)
&amp;#39;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&amp;lt; !DOCTYPE html PUBLIC &amp;#34;-//W3C//DTD XHTML
 1.1//EN&amp;#34; &amp;#34;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&amp;#34;&amp;gt;
&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34; xml:lang=&amp;#34;en&amp;#34;&amp;gt;
&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;Welcome to this python generated site&amp;lt;/p&amp;gt;
&amp;lt;h1&amp;gt;My site!&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;
&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;/html&amp;gt;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;(&lt;em&gt;Ignore the added slashes and the additional line breaks caused by wordpress&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;By overloading the &lt;code&gt;__get&lt;/code&gt;/&lt;code&gt;set&lt;/code&gt;/&lt;code&gt;delattr__&lt;/code&gt; functions a html document can be represented like a real python object model.&lt;/p&gt;
&lt;p&gt;I’ve just experimented a little bit with python code to ultimately go to write a framework to write nice dynamic python webbased applications in.&lt;/p&gt;
&lt;p&gt;Although it appears that the names of the objects (&lt;code&gt;html&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;, etc) are the tag names, they aren’t. They are the identifiers of the tags.. in case the tag isn’t set by yourself but just created for it didn’t existed it uses as tag its alleged id.&lt;/p&gt;
&lt;p&gt;The default created object when no object exists already with that id is a &lt;code&gt;tag&lt;/code&gt;. This abstract document won’t be limited to tags. I’ve just made a &lt;code&gt;styleTag&lt;/code&gt; class which allows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;d.html.head.style.body[&amp;#34;font-family&amp;#34;] = &amp;#39;verdana&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;which is basicly the same as&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;d.html.head.style.[&amp;#34;body&amp;#34;].font-family = &amp;#39;verdana&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;In contrary to the normal &lt;code&gt;tag&lt;/code&gt; class where an &lt;em&gt;item&lt;/em&gt; is an attribute, this is different in the style tag for CSS got a lot of characters which python doesn’t like (like #).&lt;/p&gt;
&lt;p&gt;Being able to manipulate a style sheet that easily allows every custom tag (maybe a &lt;code&gt;datetimepickercontrol&lt;/code&gt;) to set its own style information by just using simple python code.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;styletag&lt;/code&gt; isn’t bound to putting its emitted css in the emitted-html string itself in case it is emit-ed in a specific context like a webserver, it can even create a seperate css for this purpose.&lt;/p&gt;
&lt;p&gt;Python allows much more dynamic features in a dynamic framework like this than any other language, I`m quite enthousiastic about it and am playing with new idea’s like a little child :-).&lt;/p&gt;
&lt;p&gt;All kinds of idea’s would be welcome..&lt;/p&gt;
&lt;p&gt;Just wondering whether such a thing has already been written for Python.. anyone knows?&lt;/p&gt;</description></item><item><title>Strange spam</title><link>https://blog.affien.com/archives/2005/03/01/strange-spam/</link><pubDate>Tue, 01 Mar 2005 22:54:49 +0100</pubDate><guid>https://blog.affien.com/archives/2005/03/01/strange-spam/</guid><description>&lt;p&gt;The last few days this blog has been under heavy attack of comment spam. Although the excellent wordpress filters have put all of it in the moderation queue it still is quite some work so sift out any comments that actually are of a real person.&lt;/p&gt;
&lt;p&gt;The odd thing I noticed out of curiousity is that the links don’t even seem to work on more than half of all the spam comments. They are basicly flooding you with for them hopefully tempting comments and if someone finaly has been tempted enough to click one it doesn’t work!&lt;/p&gt;</description></item><item><title>Using exception or assertation</title><link>https://blog.affien.com/archives/2005/02/28/using-exception-or-assertation/</link><pubDate>Mon, 28 Feb 2005 18:54:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/28/using-exception-or-assertation/</guid><description>&lt;p&gt;People tend to mix up the intended use of exceptions and assertations.&lt;/p&gt;
&lt;h3 id="assertations"&gt;Assertations&lt;/h3&gt;
&lt;p&gt;Most assertation implementations will show up a form and most of them allow you to &lt;em&gt;ignore&lt;/em&gt; the assertation. I once was using a program which even asked me whether I wanted to ignore that assertation in the future.&lt;/p&gt;
&lt;p&gt;Using asserations as normal errors is wrong. Assertations aren’t meant to be errors, neither exceptions.&lt;/p&gt;
&lt;p&gt;Using assertations (as you should) is to make sure that the conditions that &lt;em&gt;should&lt;/em&gt; be right are right, if they aren’t right you will know and you know you made an error and not the program or the user.&lt;/p&gt;
&lt;p&gt;A seemingly ridiculous example is the following assertation:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ASSERT(1 + 1 == 2)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If a programmer uses the assumption that 1 + 1 is 2 and isn’t sure about this he would use an assertation to be notified when he was wrong or missed something.&lt;/p&gt;
&lt;h3 id="exceptions"&gt;Exceptions&lt;/h3&gt;
&lt;p&gt;Most people treat exceptions as failures of a piece of program. And some programmers don’t tend to clean up stuff before they throw an exception for they just think that noone wants to do anything anymore, for an exception, they think, is fatal.&lt;/p&gt;
&lt;p&gt;Exception aren’t fatal. Exceptions aren’t errors. &lt;strong&gt;Exceptions occur&lt;/strong&gt;, for they are just as the word says exceptions. You just got to handle any exception that might occur. An exception becomes fatal when this isn’t handled for it is either totaly unexpected or just unhandable, where in both cases letting the exception stay unhandled is a better alternative than using an assertation.&lt;/p&gt;</description></item><item><title>Schnappi</title><link>https://blog.affien.com/archives/2005/02/28/schnappi/</link><pubDate>Mon, 28 Feb 2005 16:05:35 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/28/schnappi/</guid><description>&lt;p&gt;For all those people that ‘like’ all those great jamba commercials:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.freegamez.de/onlinespiele/download.php?id=2231"&gt;Schnappi 1&lt;/a&gt;&lt;br&gt;
http://7dhls.7d.funpic.de/schnappishooter.swf Schnappi 2, direct link doesn’t work&lt;br&gt;
&lt;a href="http://www.estatica.de/"&gt;Sweety&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;</description></item><item><title>Command line parser update</title><link>https://blog.affien.com/archives/2005/02/27/command-line-parser-update/</link><pubDate>Sun, 27 Feb 2005 11:45:24 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/27/command-line-parser-update/</guid><description>&lt;p&gt;I made some updates on &lt;a href="http://blog.w-nz.com/archives/2005/02/26/command-line-parser-for-net/"&gt;my command line parser for .net&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;It now supports aliases and you can set whether the parameter should accept a value or not so you can use &lt;code&gt;-foo bar&lt;/code&gt; where &lt;code&gt;foo&lt;/code&gt; doesn’t accept a value and therefore &lt;code&gt;bar&lt;/code&gt; is regognized as a position dependand parameter.&lt;/p&gt;
&lt;p&gt;An example parameter definition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Parameter(Position = 0, IsMandatory = true,
AcceptsNoValue = false, Name = &amp;#34;folder&amp;#34;,
Description = &amp;#34;The folder&amp;#34;, 
Aliases = new string[]{&amp;#34;target&amp;#34;})]
public string FolderParameter
{
 get { return _FolderParameter; }
 set { _FolderParameter = value; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;(Ignore the slashes placed before the quotes, wordpress seems to add them automaticly) I also have added the &lt;code&gt;Intrepid.Automation.CommandLine.OutputHelp&lt;/code&gt; function, which outputs &lt;em&gt;help&lt;/em&gt; for the parameters of an object to a stream. Like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SUMMARY&lt;br&gt;
Creates playlists in a folder and its subfolders&lt;/p&gt;
&lt;p&gt;PARAMETERS&lt;br&gt;
-target&lt;/p&gt;
&lt;p&gt;[String excludefilter = NULL] (efilter)&lt;br&gt;
Only files not matching this regex are included&lt;/p&gt;
&lt;p&gt;[String includefilter = NULL] (ifilter)&lt;br&gt;
Only files matching this regex are included&lt;/p&gt;
&lt;p&gt;String folder (target)&lt;br&gt;
The folder&lt;/p&gt;
&lt;p&gt;[Boolean expand]&lt;br&gt;
Whether to expand referenced m3u’s&lt;/p&gt;
&lt;p&gt;REMARKS&lt;br&gt;
m3u playlists are automaticly excluded; use -excludefilter to add additional excludes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can still download the Intrepid.Clorelib assembly &lt;a href="http://w-nz.com/update/Intrepid.Corelib.zip"&gt;here&lt;/a&gt; and you still may only use it for non-commercial open-source usage and may not change/reverse engineer/etc it in any way.&lt;/p&gt;
&lt;p&gt;Hope it will prove usefull :-).&lt;/p&gt;</description></item><item><title>Command line parser for .net</title><link>https://blog.affien.com/archives/2005/02/26/command-line-parser-for-net/</link><pubDate>Sat, 26 Feb 2005 19:37:53 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/26/command-line-parser-for-net/</guid><description>&lt;p&gt;I just wrote a command line parser for .net which parses the command line similar to the way &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=25915"&gt;Monad’s cmdlets&lt;/a&gt; do it, with the key difference that this still is for the normal .exe executables.&lt;/p&gt;
&lt;p&gt;It’s very simple, first get yourself a program class, which contains some properties you want the user able to set via the commandline and apply the &lt;code&gt;Parameter&lt;/code&gt; attribute:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class CopyProgram
{
 private string _Source;
 [Parameter(Position = 0, IsMandatory = true)]
 public string Source
 {
 get { return _Source;}
 set { _Source = value; }
 }
 private string _Target;
 
 [Parameter(Position = 1, IsMandatory = true)]
 public string Target
 {
 get { return _Target;}
 set { _Target= value; }
 }
 
 private bool _WalkRecursivly;
 [Parameter(Name = &amp;#34;recursivly&amp;#34;)]
 public bool WalkRecursivly
 {
 get { return _WalkRecursivly;}
 set { _WalkRecursivly= value; }
 } 

 static void Main(string[] args)
 {
 new Program().Run(args);
 }

 void Run(string[] args)
 {
 CommandLine.ParseCommandLine(args, this);
 
 // Do stuff here
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;CommandLine.ParseCommandLine&lt;/code&gt; function takes care of parsing the command line string array and filling the required properties of the class provided.&lt;/p&gt;
&lt;p&gt;You can call this program in a few different ways:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;copy.exe c:\source.txt c:\target.txt
copy.exe -s c:\source.txt -target c:\target.txt
copy.exe -targ c:\target.txt c:\source.txt -r
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Although it only required around 250 lines of code it certainly is an enourmous time safer and makes stuff a lot easier for the user.&lt;/p&gt;
&lt;p&gt;At the moment I’m programming a few small utilities and will change the code a bit and fix some bugs if any.&lt;/p&gt;
&lt;p&gt;For those interesting in testing it themselves (I encourage it), just download the &lt;a href="http://w-nz.com/update/Intrepid.Corelib.zip"&gt;Intrepid.Corelib .net 2 assembly&lt;/a&gt;*. The classes required are in the &lt;code&gt;Intrepid.Automation&lt;/code&gt; namespace. Please send any bug reports to: &lt;a href="mailto:bas.westerbaan@gmail.com"&gt;bas.westerbaan@gmail.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(* You may use everything in the Intrepid.Corelib assembly freely for non-commercial open-source usage. Do not modify or reverse engineer the assembly in any way.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;br&gt;
Got rid of some bugs and added the &lt;code&gt;RequiresValue&lt;/code&gt; property to &lt;code&gt;ParameterAttribute&lt;/code&gt;. Will replace lateron with &lt;code&gt;Type&lt;/code&gt;, this allows you to use &lt;code&gt;-e bleh&lt;/code&gt; where -e takes no value and bleh is interpreted as a nameless parameter. Will add alliases too.&lt;/p&gt;</description></item><item><title>Running linux in windows</title><link>https://blog.affien.com/archives/2005/02/23/running-linux-in-windows/</link><pubDate>Wed, 23 Feb 2005 21:31:59 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/23/running-linux-in-windows/</guid><description>&lt;p&gt;&lt;a href="http://www.pcmag.com/article2/0,1759,1768170,00.asp"&gt;Opinion Column by PC Magazine: How to Kill Linux&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We better not tell him about &lt;a href="http://cygwin.com/"&gt;Cygwin&lt;/a&gt; 😉&lt;/p&gt;</description></item><item><title>Serialization</title><link>https://blog.affien.com/archives/2005/02/22/serialization/</link><pubDate>Tue, 22 Feb 2005 20:13:29 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/22/serialization/</guid><description>&lt;p&gt;Yey, I am your average developer and I made yet another program with some kind of data I want to be able to dump on the hard drive and be able to grab it again. Let’s use serialization!&lt;/p&gt;
&lt;p&gt;Serialization was meant to be a tool for developers to pick up their data from the memory sqeesh it a bit and let it be dropped onto the hard drive, sparing hours of work making a custom data serializer to an existing format or even worse: a home made format. However there are a lot of reasons &lt;a href="http://www.thecodeproject.com/dotnet/noserialise.asp"&gt;why not to serialize in .net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ok, so Iâ€™ll spend endless hours to make my own algorithms to save my data producing thousands of almost similar lines of code, but just not nearly similar enough to prevent copy and paste bugs. After admiring my very own labor there will be twice as much time debugging the code.&lt;/p&gt;
&lt;p&gt;… mm… isnâ€™t there another way to serialize, which doesnâ€™t have too much adverse sides?&lt;br&gt;
ok, what are the demands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It shouldn’t effect the way you design classes.&lt;/strong&gt;&lt;br&gt;
Thus:&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It should not be based on public fields or properties.&lt;/strong&gt;&lt;br&gt;
This is probably the foremost cause of type design restrictions due to serialization support. While dropping public fields as basis of the serialization allows protection of certain fields, it also prevent those fields to be accessed by some kind of automated serialization. This however is only a minor setback: youâ€™ll need to create Serialize and Deserialize methods to control serialization. A part of the current .net serialization also relies on this principle, however there should be some modification:&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The actual implementation of the (de)serialization algorithm should only optionaly be in the type declaration.&lt;/strong&gt;&lt;br&gt;
The original .net serialization restricts the user to serializing souly his/her own types. If string was to be unserializable you wouldnâ€™t be able to tell some kind of serialization handler: “hey, here is a type, serialize it” because this handler would find that you are a moron, trying to serialize a string which is not serializable because there is no Serialize nor a Deserialize method. You would be forced to create your own string serialization algorith in every single type you want to serialize and which contains a string. While this is doable image that the string has been changed in a complex data structure containing inter references… You still would be spending a lot of time creating a serialization algorithm for someone elses type. The most obvious solution to this problem is allowing some kind of TypeSerializer which could be ‘registered’ to a serialization provider. The only drawback to this solution is that you canâ€™t access any private fields, therefore you arenâ€™t able to truly serialize every type and there are scenarioâ€™s imaginable where serialization is impossible. There is no easy solution to this. Luckily this should be a rare event.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You should be able to handle reference types as reference types.&lt;/strong&gt;&lt;br&gt;
The most fundamental flaw in the current .net serialization in my opinion is being unable to serialize a from multiple locations referenced type only once in other words preserving the ‘reference equals’. Programmers have been known to use ‘ID’s’ to preserve some kind of referencing ability. This seems like a nice simple solution, only draining processor time every time an Id needs to be solved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There should be a Serialization and Deserialization Host/Provider.&lt;/strong&gt;&lt;br&gt;
Such a provider has 3 main function, justifying its existence:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storing type serializers&lt;/strong&gt;&lt;br&gt;
All different type serializers could also be stored in a static list, but this would enforce the ‘use’ of every single one of them (during lookup). You donâ€™t want to know how to deserialize meat when you are vegetarian!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storing serialized signatures together with their (deserialized) objects&lt;/strong&gt;&lt;br&gt;
The only way you are able to preserve references while being able to serialize on demand is to keep track of the already serialized reference type object or the already deserialize reference objects. This could also be managed in a static list however the ‘same’ rule applies: A ice cream shop doesnâ€™t need to know what kinds of meats already have been serialized.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Providing Serialize and Deserialize methods to the Serialize and Deserialize algorithms by being an argument.&lt;/strong&gt; &lt;br&gt;
The provider should automatically redirect the serialization request for a field of a serialize method to the serialize method of the type of the field, while passing itself as serialization provider along to the next ones in the chain. While this improves user comfort it also gives the serializer the ability to store the created ‘serialized object’ or in the case of a deserializer the deserialized object. There is a catch to this system, when there is the possibility of inter referencing this could cause an endless (until the stack runs out) chain. When the pork meat isnâ€™t finished serializing itâ€™s fields, the olives donâ€™t know that it is busy and will invoke a second serialization of pork meat causing a second serialization of the olives and so on. This is easily solved by a not so elegant use of a Register method inside the Serialize or Deserialize method. This method adds the not yet totally (De)serialized object to the referenced object and serialized objects pairs allowing any objects down the graph to use the correct reference.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It should be able to coup with any changes.&lt;/strong&gt;&lt;br&gt;
This is a hard one and this is a problem bugging all areas of development. There is no easy solution to this. The only way to handle this is to make some sort of conversion for older files or to have different types of serialized object of the same (sometimes changed) type. It would be something like that you have the serialized type of salade mix containing the amount of salad and another one which also contains the amount of tomatoes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It should get rid of the string key value pair used by the microsoft serialization.&lt;/strong&gt;&lt;br&gt;
Strings are slow and interpreting them is even slower. Itâ€™s like describing the forms of the figures in your bank account with metaphors. There is one good thing about key value pairs and that it that they are unordered. This barely manages to try to hide the fact that itâ€™s too slow. An alternative could look like this:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A Guid&lt;/strong&gt; regogniced by the deserialization provider as a specific version of the serialized version of a specific type. This would trash any problems with extensibility of the serialized type because you would simple copy and paste the algorithm and kick iit a bit (to fit your demands) and supply it with a new Guid while preserving the old algorithm and possibly adding a friendly obsolete exception. Any type which supplies serialization and deserialization to itself or to another type should include a list of accepted guids.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A list of referenced serialized objects&lt;/strong&gt; which could contain the fields of the type. How this is used is to the creator of the serialization and deserialization algorithm.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A byte array&lt;/strong&gt; containing any ‘personal’ data of a type whos data isnâ€™t distributed among fields (like natives).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It should be secure.&lt;/strong&gt;&lt;br&gt;
The memory is pretty save due to access restrictions and the fact that only the application controlling the memory really knows what a byte means, however the hard disk or even worse the internet isnâ€™t really any match for the protection the memory offers. There are a few ways to protect data on your hard disk. One of those is access policy. However this is somewhat unpractical and canâ€™t be applied to internet traffic. Maybe the best solution is using encryption, this could be applied to the hole file, inefficient, but effective or sensitive data inside of a serialized file could be stored into the ‘raw’ data and be encrypted by the type serializer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think that there could be an implementation of serialization able to meet these demands. If it does meet these demands there would be little objection left to use and it would be favorable above even the most optimized hand crafted data ‘dumpers’. I will do some more research and there could be a sequential more concrete article with some closer-to-code talk.&lt;/p&gt;
&lt;p&gt;P.S. As you may have noticed the posts now contain an author specifies and you may have also noticed this post wasnâ€™t written by the usual author. Iâ€™ve joined Bas Westerbaan writing posts for Intrepid Blog.&lt;/p&gt;</description></item><item><title>Regular Expressions in .Net</title><link>https://blog.affien.com/archives/2005/02/21/regular-expressions-in-net/</link><pubDate>Mon, 21 Feb 2005 19:05:44 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/21/regular-expressions-in-net/</guid><description>&lt;p&gt;Regular Expressions in .Net (&lt;code&gt;System.Text.RegularExpression&lt;/code&gt;) are fast!&lt;/p&gt;
&lt;p&gt;When creating a &lt;code&gt;Regex&lt;/code&gt; with the compile flag the regex will actually be compiled to very optimized native assembly which makes the .net regular expression library faster than any c# code you could write for one specific case.&lt;/p&gt;
&lt;p&gt;This was a pleasant suprise 🙂 for now I know I can use regular expression for all those small things like parsing input.&lt;/p&gt;</description></item><item><title>Why Php sucks (and I still use it)</title><link>https://blog.affien.com/archives/2005/02/21/why-php-sucks-and-i-still-use-it/</link><pubDate>Mon, 21 Feb 2005 17:57:09 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/21/why-php-sucks-and-i-still-use-it/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Php is slow&lt;/strong&gt;, not just slow, but really slow. A simple benchmark runs in 1 milisecond in C. It takes 2 miliseconds for .Net. Python takes 600 miliseconds for instead of a native assembly language or jit-ted language it is an interpreted language. But Php, even though it also is an interpreted language and hasn’t got the enourmous object overhead Python has got it still takes 12000 miliseconds, that are 12 seconds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stupid work arounds&lt;/strong&gt;, for Php itself is rather slow you got to rely as much as you can on function calls instead of doing anything yourself. It is for instance faster to load a list by deserializing a string than just reading line by line through a file although the deserialization would be way faster if both methods would be implemented nativly. Another little issue here is that most very quick functions in Php are only available in the newer versions (eg. &lt;code&gt;file_set_contents&lt;/code&gt;), this requires you to add an if statement with a home made implementation of the function which usualy is slower by a factor of 10. You can choose to use an alternative way which doesn’t exactly implements the functions of the function you require to use but still does the job for the circumstance (better) (eg. not rewriting &lt;code&gt;file_put_contents&lt;/code&gt; when it isn’t available when you want to streamingly write data to a file but rather call &lt;code&gt;fwrite&lt;/code&gt; a few times which gets rid of having the whole file in the memory in a string at a time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State less&lt;/strong&gt; Although the Http protocol is a stateless protocol that doesn’t have to mean that a server side scripting framework should be stateless too. Although Php attempts to become statefull by using a session implementation by serializing a session array on the harddisk for every session this isn’t very efficient. Even one global array that persists between requests would result in such a performance boost. Not only for it doesn’t require file reads, writes, serialization and deserialization (and optionaly queries when you don’t like the php session system), but also for it would allow you to store that little bit of important cache between sessions that otherwise would have needed to be read, deserialized, serialized and written again, for every mere page view!&lt;br&gt;
Allowing such a persistant array however poses a security risk in the way Php works at the moment. They should add contexts to allow one instance of apache on which mod_php runs to execute files in different context, each with its own settings (and persistant data).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There is no satisfying solution in Php&lt;/strong&gt; For every single common issue in Php there is no simple solution, that works perfectly or even reasonbly well.&lt;br&gt;
Take for instance templates. There are basicly a few ways to handle templates in Php. Usualy it comes down to either caching &lt;code&gt;.php&lt;/code&gt;-scripts which are than executed as &lt;a href="http://smarty.php.net/"&gt;smarty&lt;/a&gt; does, or using a class for every major template section where every function fetches a template bit. In both these methods executing Php code is required to just only replace a certain tag with an replacement. Php has been designed to do a lot more than that and contains a lot of overhead during interpretation. Using &lt;code&gt;str_replace&lt;/code&gt;‘s is a lot faster than a php block inline or even using instring php variables (&lt;code&gt;&amp;quot;Example: {$example}&amp;quot;&lt;/code&gt;). The second way using classes and functions is even worse for the whole class and all functions first need to be loaded in the memory and basicly are a lot slower.&lt;br&gt;
The proper way to use templates is streaminly inputting and replacing tags with their values and outputting it. This isn’t possible for &lt;em&gt;php is slow&lt;/em&gt; and loading the whole template in a string is even faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only reason why I still use Php is for it is just the number one supported server side scripting language.&lt;/p&gt;
&lt;p&gt;Why is world wide web not fair?&lt;/p&gt;</description></item><item><title>Got GMail invites left?</title><link>https://blog.affien.com/archives/2005/02/19/got-gmail-invites-left/</link><pubDate>Sat, 19 Feb 2005 14:05:43 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/19/got-gmail-invites-left/</guid><description>&lt;p&gt;Don’t go to every forum and post a topic that people can get them by mailing you.&lt;/p&gt;
&lt;p&gt;Just donate them to &lt;a href="http://isnoop.net/gmail/"&gt;http://isnoop.net/gmail/&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;It is the second link in google when searching for gmail invites. (first is google itself)&lt;/p&gt;
&lt;p&gt;If you want your invites to be used send your invites to them, as I did.&lt;/p&gt;</description></item><item><title>Microsoft Anti Spyware</title><link>https://blog.affien.com/archives/2005/02/17/microsoft-anti-spyware/</link><pubDate>Thu, 17 Feb 2005 18:11:31 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/17/microsoft-anti-spyware/</guid><description>&lt;p&gt;&lt;a href="http://www.joelonsoftware.com/items/2005/02/17.html"&gt;Microsoft Anti Spyware beta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It looks to work well, it even detects some adware that &lt;a href="http://www.lavasoftusa.com/software/adaware/"&gt;adaware&lt;/a&gt; didn’t remove.&lt;/p&gt;
&lt;p&gt;It is said by many people that using more than one anti-adware program is the best way for they all don’t catch everything. Joel suggests &lt;a href="http://www.joelonsoftware.com/items/2005/02/17.html"&gt;why Microsoft Anti Spyware wouldn’t catch everything&lt;/a&gt;: conflicts of interest.&lt;/p&gt;
&lt;p&gt;A lot of money is made by redistributing spyware/adaware/malware on people’s computers. They could easily bribe some anti-adware software developers to ignore their adware.&lt;/p&gt;
&lt;p&gt;I just got to find an anti-adware program that is proffesional enough to clean my computer, and isn’t bribed to leave some.&lt;/p&gt;
&lt;p&gt;The problem is that there are a lot of anti-adware programs, most of them are adware themselves.&lt;/p&gt;</description></item><item><title>Blog updated</title><link>https://blog.affien.com/archives/2005/02/17/blog-updated/</link><pubDate>Thu, 17 Feb 2005 17:21:22 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/17/blog-updated/</guid><description>&lt;p&gt;The blog has been updated to 1.5.&lt;/p&gt;
&lt;p&gt;It adds a lot of nice new features and I would like to advice other users to &lt;a href="http://wordpress.org/development/2005/02/strayhorn/"&gt;upgrade now&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new skin is the new default skin that comes with WP1.5.&lt;/p&gt;
&lt;p&gt;When I find time I’ll adapt it a bit to make it a bit less default.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; Just noticed that the wordpress ACP looks horribly scrambled in Firefox, looks all right in internet explorer though :(.&lt;/p&gt;</description></item><item><title>Skins and performance in PHP</title><link>https://blog.affien.com/archives/2005/02/13/skins-and-performance-in-php/</link><pubDate>Sun, 13 Feb 2005 23:58:10 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/13/skins-and-performance-in-php/</guid><description>&lt;p&gt;There are several ways to use skins in PHP, I’ve put some through a performance test.&lt;/p&gt;
&lt;p&gt;Basicly you can use either evaluated PHP or a string that will undergo str_replace’s.&lt;/p&gt;
&lt;p&gt;When evaluating PHP in a file it seems to be faster than replacing tags in a string. This for PHP streams through the file during execution instead of handling one big string. The difference is minimal though (15% in my tests).&lt;/p&gt;
&lt;p&gt;Although when the PHP code is placed in a string instead of in a file which has to be done in case a string is cached in a database or is generated from compiling from another format it is significantly slower than using str_replace’s on a normal string (600%!), this is because the original sourcecode, the intermediate code and the return from the code all take a lot of memory.&lt;/p&gt;
&lt;p&gt;Either use cached PHP files or a string with tags instead of PHP code in a database, never the otherway around (what happens very often).&lt;/p&gt;</description></item><item><title>Caching in PHP</title><link>https://blog.affien.com/archives/2005/02/11/caching-in-php/</link><pubDate>Fri, 11 Feb 2005 17:06:03 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/11/caching-in-php/</guid><description>&lt;p&gt;It is usefull to cache certain things between Php script executions.&lt;br&gt;
Some boards written in Php cache the forum architecture so a difficult query hasn’t got to be run every time a guest views the board.&lt;/p&gt;
&lt;p&gt;There are a few ways to cache data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Php script&lt;/strong&gt;. Data will be stored as a normal php file which will be included during execution&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Serialized object in file&lt;/strong&gt;. Data will be serialized and dumped to a file which will be read every page view&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database storage&lt;/strong&gt;. Data will be serialized and stored in a database and queried every page view.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are a lot of myths about using a database would be way slower than a normal php file.&lt;/p&gt;
&lt;p&gt;I’ve run a few tests caching a ~16kB php array, the results:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Serialized object stored in file:&lt;/strong&gt; 0.0015ms&lt;br&gt;
&lt;strong&gt;Object in PHP script:&lt;/strong&gt; 0.0121ms&lt;br&gt;
&lt;strong&gt;Serialized object stored in mySQL database:&lt;/strong&gt; 0.0015ms&lt;/p&gt;
&lt;p&gt;It seems to be quicker to use a serialized array in a file as configuration file than a &lt;code&gt;config.php&lt;/code&gt; php script!&lt;/p&gt;
&lt;p&gt;Databases although just as quick as normal files are favored by me for they are much more scalable.&lt;/p&gt;</description></item><item><title>Gamma Wave Effect on a real electric guitar</title><link>https://blog.affien.com/archives/2005/02/07/gamma-wave-effect-on-a-real-electric-guitar/</link><pubDate>Mon, 07 Feb 2005 15:15:05 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/07/gamma-wave-effect-on-a-real-electric-guitar/</guid><description>&lt;p&gt;Finaly I got grip of a recording of an electric guitar without distortion and applied the gamma wave distortion on it:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/uploads/gammas.png"&gt;Sine gamma effect results and positive linear gamma results&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/uploads/gammanlins.png"&gt;Negative linear gamma effect results&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Gamma Wave Effect</title><link>https://blog.affien.com/archives/2005/02/07/gamma-wave-effect/</link><pubDate>Mon, 07 Feb 2005 12:40:09 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/07/gamma-wave-effect/</guid><description>&lt;p&gt;As promised a few pictures of the electric guitar effects we’re working on,&lt;/p&gt;
&lt;p&gt;first up, the gamma wave effect.&lt;/p&gt;
&lt;p&gt;The gamma wave effect pulls the amplitudo’s either to the 0 line or the -1/1 line, just like the gamma on your monitor does:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/lineargammanegative.png" alt="Max Negative Linear Gamma Applied"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/sinegammapositive.png" alt="Max Positive Sine Gamma Effect"&gt;&lt;/p&gt;
&lt;p&gt;The effect basicly makes the wave a lot louder and gets rid of the faint sounds. When on fully applied as in the images above it also creates some distortions due to either making the wave unharmonic-ish or getting rid of the nuances.&lt;/p&gt;
&lt;p&gt;Another image taken on a higher oscilation (smaller zoom):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/sinegammapositive2.png" alt="Max Pos Sine Gamma 2"&gt;&lt;/p&gt;
&lt;p&gt;This clearly shows the distortion&lt;/p&gt;
&lt;p&gt;(The inversion of peak and valley doesn’t matter for for sound only the transition from a valley to a peak matters)&lt;/p&gt;</description></item><item><title>Electric Guitar Distortion</title><link>https://blog.affien.com/archives/2005/02/07/electric-guitar-distortion/</link><pubDate>Mon, 07 Feb 2005 00:02:08 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/07/electric-guitar-distortion/</guid><description>&lt;p&gt;As I said before I am working with some others on a software based distortion. I finaly got the base running pretty smoothly but the main obstacle is how to create that distortion electric guitars use.&lt;/p&gt;
&lt;p&gt;We came up with about 3 different methods:&lt;/p&gt;
&lt;p&gt;(When I got my osciloscope control working I’ll take before and after pictures, for now I ain’t sure how the formula’s effect real-world sound yet)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gamma corrections&lt;/strong&gt;&lt;br&gt;
This works a bit like the gamma of your monitor. The input for graph for gamma correction is called the epsilon which comes in 2 forms, linear and sine. The first one creates a more distortion like sound than the latter but also makes the wave not harmonic anymore which possible means that most of the distortion like sound is caused by the speakers not handling unharmonic waves very well. The latter one only sounds near the amplitudo distorted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sharpening valleys/tops&lt;/strong&gt;&lt;br&gt;
This method requires some buffering of the current top (or valley) of the wave and sharpenes it by a specific amount. This works a bit like the gamma correction method although it works on every volume making it usefull too for low-volume sounds. The major problem is that it requires tracking a top or a valley, which with a high bitrate requires a really big buffer to analyze, and it has a delay of one top/valley. The big problem is that this isn’t ideal for live playing for which it was designed, a delay of a few extra hundreds of a second would be noticable and it is fairly possible that this algorithm requires too much resources.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Adjusting speed resistance&lt;/strong&gt;&lt;br&gt;
At a certain point in a wave you can derive the speed and the angle. By registering the original speed and resistance of the wave a derived one can be created which could leed to sharper or softer edges of a top/valley just as the previous method but without being required to analyze the whole top/valley. We’re hoping this method will work best but this is just a concept hoping to work out as it should.&lt;/p&gt;
&lt;p&gt;If anyone actually knows how analog distortions work exactly we would be more than happy to learn about it, just comment.&lt;/p&gt;
&lt;p&gt;More on this to come…&lt;/p&gt;</description></item><item><title>Working on a software based distortion for the electric guitar</title><link>https://blog.affien.com/archives/2005/02/05/working-on-a-software-based-distortion-for-the-electric-guitar/</link><pubDate>Sat, 05 Feb 2005 21:27:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/05/working-on-a-software-based-distortion-for-the-electric-guitar/</guid><description>&lt;p&gt;At the moment I am busy creating a software based distortion for an electric guitar.&lt;/p&gt;
&lt;p&gt;The most challenging part is getting effects to work, to explain this in more detail you need to know how a computer handles audio.&lt;/p&gt;
&lt;p&gt;Sound itself is nothing more than a vibration in the air. It can be represented by the amount of force the air is pushing or pulling.&lt;/p&gt;
&lt;p&gt;A tone of a specific frequency would look like:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/wave2.png" alt="A wave"&gt;&lt;/p&gt;
&lt;p&gt;A computer stores sound by sampling the amplitude of the air at regular interfals.&lt;/p&gt;
&lt;p&gt;It would be easy to write a program to increase the frequency of the sound above, but a normal sound doesn’t look that regular:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/wave1.png" alt="A wave"&gt;&lt;/p&gt;
&lt;p&gt;Increasing the bass or treble of that wave would require some advanced algorithms, which take time to execute which creates a larger delay. One thing that a distortion shouldn’t do is lag.&lt;/p&gt;
&lt;p&gt;More on this when some stuff is working.&lt;/p&gt;</description></item><item><title>PHP Security Consortium</title><link>https://blog.affien.com/archives/2005/02/04/php-security-consortium/</link><pubDate>Fri, 04 Feb 2005 21:19:55 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/04/php-security-consortium/</guid><description>&lt;p&gt;The &lt;a href="http://phpsec.org/"&gt;PHPSC&lt;/a&gt; is a site managing a lot of resources on PHP security.&lt;/p&gt;
&lt;p&gt;For all those starting or sometimes using PHP this is a must read.&lt;/p&gt;
&lt;p&gt;Also I’d advice for people who want to know whether there site is safe enough is to try to play the other site by trying out hacking yourself: &lt;a href="http://www.hackthissite.org/"&gt;hackthissite.org&lt;/a&gt;. It is easier than you might have thought.&lt;/p&gt;</description></item><item><title>Image echoing</title><link>https://blog.affien.com/archives/2005/02/02/image-echoing/</link><pubDate>Wed, 02 Feb 2005 00:01:37 +0100</pubDate><guid>https://blog.affien.com/archives/2005/02/02/image-echoing/</guid><description>&lt;p&gt;An almost realtime webcam with a monitor is always fun, espacialy when the bad quality requires the software to compensate resulting in some nice effects after several passes:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/picture49.jpg" alt="imageechoing"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.w-nz.com/uploads/picture61.jpg" alt="imageechoing2"&gt;&lt;/p&gt;</description></item><item><title>C# rapid game development</title><link>https://blog.affien.com/archives/2005/01/30/c-rapid-game-development/</link><pubDate>Sun, 30 Jan 2005 01:32:16 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/30/c-rapid-game-development/</guid><description>&lt;p&gt;I’ve been working on a Direct 3d game in C++ for quite some while now. I recently tried using Direct 3d in C# and it took me only 15 minutes to get a basic framework running instead of the 5 hours in C++. Now I know that C# isn’t favoured for game developing for it is slower; it is rapid development and a lot more maintainable.&lt;/p&gt;
&lt;p&gt;I did some test on how much the difference would be between having a C# or C++ game engine.&lt;/p&gt;
&lt;p&gt;The results were quite supprising:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C# is slower, but when letting as much as possible be done by the graphics card and direct X instead of C# code the difference between C# and C++ is neglected also due to superior threading control and runtime memory managment of C#&lt;/li&gt;
&lt;li&gt;C# develops a lot faster than C++, far faster than I expected initialy&lt;/li&gt;
&lt;li&gt;Threading and timing the renders and other operations is a lot faster in C# than it is in C++. Also multithreading doesn’t generate as much problems in C# as it does in C++. And maybe even important; debugging threads in C# is a lot easier than in C++&lt;/li&gt;
&lt;li&gt;The second critical area (after the rendering) is the gameplay engine. Most games need to use scripts for it is unfeasable to hardcode everything. C# doesn’t has to use scripts for using seperate .net dll’s works quite well and is hundreds times faster too&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wonder what will be the first major game that will be written in .net. It certainly should atract some attention by game developers.&lt;/p&gt;</description></item><item><title>Server transfer: downtime</title><link>https://blog.affien.com/archives/2005/01/30/server-transfer-downtime/</link><pubDate>Sun, 30 Jan 2005 00:39:20 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/30/server-transfer-downtime/</guid><description>&lt;p&gt;I will soon own a quite cheap virtual server (by &lt;a href="http://greent.info"&gt;greenT&lt;/a&gt;, great company) which will give me way more flexibility than the current shared server account on which &lt;a href="http://w-nz.com"&gt;w-nz.com&lt;/a&gt; is located.&lt;/p&gt;
&lt;p&gt;I’ll transfer my current site to the new virtual server from the current shared server account (&lt;a href="http://w-nz.com/"&gt;w-nz.com&lt;/a&gt;; &lt;a href="http://xr12.com/"&gt;xr12.com&lt;/a&gt;; &lt;a href="http://intrepidsoft.net"&gt;intrepidsoft.net&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;In the worst case this could result in domain problems, transfer problems and lack of time to get it done and therefore a lot of downtime.&lt;/p&gt;
&lt;p&gt;So when &lt;a href="http://w-nz.com"&gt;w-nz.com&lt;/a&gt; is down please be patient and if you want to email me use &lt;a href="mailto:bas.westerbaan@gmail.com"&gt;bas.westerbaan@gmail.com&lt;/a&gt; instead of my @w-nz.com email addresses.&lt;/p&gt;</description></item><item><title>Negative .Net myths busted</title><link>https://blog.affien.com/archives/2005/01/27/negative-net-myths-busted/</link><pubDate>Thu, 27 Jan 2005 16:04:31 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/27/negative-net-myths-busted/</guid><description>&lt;p&gt;There are a lot of negative myths about .net which people tend to use to favor the &lt;em&gt;traditional&lt;/em&gt; languages like C++ above .net. I’ve busted the ones I read frequently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The GC is really slow&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;malloc&lt;/code&gt; is way slower! The Garbage Collect of .net actually is faster than any Unmanaged code for it nows whether a value is a reference (pointer) and therefore can move objects in the memory. The GC puts objects of about the same age (generation) close to eachother in the memory. Objects tend to refer and use objects in the same generation. The processor itself doesn’t directly load a value from the memory but loads a whole block of a few KiloBytes in the Cache. When the processor directly caches all the objects which one object uses it just runs a lot faster for working from the cache is a lot faster than recaching different parts of the memory over and over again which happens with unmanaged languages which just put objects where there is free space.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interpreting that stupid Intermediate Language is damned slow&lt;/strong&gt;&lt;br&gt;
.Net doesn’t interpret its IL, it compiles and optimizes IL runtime&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compiling runtime is very slow anyways&lt;/strong&gt;&lt;br&gt;
(That compiling a C++ is slow doesn’t mean that .Net is slow) It saves a lot of time for compiling at runtime allows great optimalisations like getting rid of unreachable code and inlining depending on the current runtime variables. Also operations can be compiled with processor specific optimalisations from one IL source. Most of the resource intensive compiling is done at the startup of the application, it is done while the program is running too but that really makes it a lot faster instead of slower&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If I write assembly myself it will be way superior to anything .Net can generate&lt;/strong&gt;&lt;br&gt;
.Net can’t make all the optimalisations possible for it would take longer to analyse code than the optimalisation would gain. But usualy it creates still very optimised code. The big problem with writing very optimised assembly yourself is that the most optimised code is very processor specific and would be very hard to port, and even worse to maintain. Wanting to add one little extra feature could let you rewrite the whole code again. (Yes I indeed have made programs with assembly). Languages which avoid this a bit like C++ still require you to make a different build for every specific processor when fully optimising. Also it is nearly impossible to debug fully optimised unmanaged code but in .Net it still provides you with at least the functionname in which it has happened with the offset (try to accomplish that with C++ in release mode)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The runtime is soooo damned big, it sucks&lt;/strong&gt;&lt;br&gt;
20 Mb’s isn’t a lot. It only has got to be downloaded once, and the .net framework is in Windows Update so everyone who updates his computer would have it installed by now. Usualy there is room enough on your software installation CD to include .net, it is more than worth those 20 mb. Also languages like C++ require certain runtimes which arent that cooperative. Does ‘DLLHell’ ring a bell?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The .net library naming SUCKS&lt;/strong&gt;&lt;br&gt;
Yeah.. its naming is different than what MFC uses. At least the naming is very consistant which is way more important than ‘nice naming’, although when seeing some C++ API names used I still wonder why someone could prefer that above the clear .Net naming&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The .net library itself sucks&lt;/strong&gt;&lt;br&gt;
Really? Like what? What can’t it do?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can’t use API calls like CreateFile&lt;/strong&gt;&lt;br&gt;
Now I can’t…&lt;br&gt;
&lt;code&gt;[DllImport(&amp;quot;kernel32.dll&amp;quot;, SetLastError = true)]public static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);&lt;/code&gt;&lt;br&gt;
… now I can!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.Net sucks cause it is Microsoft&lt;/strong&gt;&lt;br&gt;
Yeah, so what. .Net is a ECMA standard so you are pretty free to use it, and if there is a catch then that one hasn’t been exploited yet for on linux people are happily using mono to run .net stuff&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Avalon</title><link>https://blog.affien.com/archives/2005/01/25/avalon/</link><pubDate>Tue, 25 Jan 2005 22:42:46 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/25/avalon/</guid><description>&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=C8F904E1-B4CA-402B-ACCF-AAA2BD60DA74&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=C8F904E1-B4CA-402B-ACCF-AAA2BD60DA74&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When having Avalon installed it adds a few new project templates to my Visual C# 2005 express, with which avalon applications can be made. Avalon is a Window system which uses xml files to define a form. At the moment I couldn’t find a designer neither reference to it in the help files and assume it isn’t implemented yet, which is rather a pain for creating a form by editing Xml by hand is just a pain: Xml is hard to write and I am just too dependant on the user friendlyness of the form designer.&lt;/p&gt;
&lt;p&gt;When compiling Avalon generates classes and serialized data files in your application to replace the Xml files.&lt;/p&gt;
&lt;p&gt;So what does it basicly do? Lets you design your forms easily (although there isn’t a proper designer yet) maintaining a good performance by replacing the slow Xml files by generated classes and serialized resources compile-time.&lt;br&gt;
Having a few test applications decompiled and having looked at the sdk it seems that Avalon can do practicly the same as the current Windows.Forms dll.&lt;br&gt;
So now I wonder, in what way would Avalon be better than using the great current form designer and the Windows.Forms dll?&lt;/p&gt;</description></item><item><title>Intrepid Countdown</title><link>https://blog.affien.com/archives/2005/01/25/intrepid-countdown/</link><pubDate>Tue, 25 Jan 2005 22:31:26 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/25/intrepid-countdown/</guid><description>&lt;p&gt;Very simple program I wrote in about 1 hour with c# (I love its productivity) to keep track of certain events:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/update/IntrepidCountDown-1.0.0.1.exe"&gt;http://w-nz.com/update/IntrepidCountDown-1.0.0.1.exe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It basicly runs in the background and notifies you of an event or a few minutes before one which you can add yourself.&lt;/p&gt;</description></item><item><title>Electrical Resistance</title><link>https://blog.affien.com/archives/2005/01/25/electrical-resistance/</link><pubDate>Tue, 25 Jan 2005 10:58:49 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/25/electrical-resistance/</guid><description>&lt;p&gt;&lt;code&gt;R = t / C&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Electrical Resistance equals Time per Electrical Capacity.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Variable sized floating points</title><link>https://blog.affien.com/archives/2005/01/22/variable-sized-floating-points/</link><pubDate>Sat, 22 Jan 2005 11:13:50 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/22/variable-sized-floating-points/</guid><description>&lt;p&gt;A lot of selfrespecting programming languages have got Integer classes which theoraticly can have an unlimited size by using a dynamic array underneath it.&lt;br&gt;
Python got it, and lots of others too.&lt;br&gt;
But still, they haven’t got a variable sized floating point, which I find odd for it shouldn’t be a big problem to create:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wrap one existing variable sized Integer&lt;/li&gt;
&lt;li&gt;Add an integer which points to the place where the point will be&lt;/li&gt;
&lt;li&gt;Add operator overrides to get it working&lt;/li&gt;
&lt;li&gt;Add an integer which specifies how much numbers after the dot there will be&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The later one is quite important to have got. We wouldn’t want &lt;code&gt;1 /3&lt;/code&gt; causing an infinite loop.&lt;/p&gt;
&lt;p&gt;You even could do it a second way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wrap &lt;strong&gt;two&lt;/strong&gt; existing variable sized Integers.&lt;/li&gt;
&lt;li&gt;Add overriden operators to get it working&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These 2 integers would represent a fraction: &lt;code&gt;a / b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By storing the fraction in stead of the result you are actually very precise, although some numbers cannot be represented in this way, but can be approached.&lt;/p&gt;</description></item><item><title>Subtext</title><link>https://blog.affien.com/archives/2005/01/16/subtext/</link><pubDate>Sun, 16 Jan 2005 15:13:51 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/16/subtext/</guid><description>&lt;p&gt;&lt;a href="http://www.subtextual.org"&gt;Subtext&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I like subtext, I am just wondering how it would be possible to create a big practical project in it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How would it do async operations? GUI’s; networking… If there is no difference between runtime and execution time this could be very hard to visualize&lt;/li&gt;
&lt;li&gt;How would this ever perform properly? Compiling would just do but when debugging a big application it would get rather slow. When it would get dynamic, meaning that the code can drag-n-drop itself, it would be virtually impossible to get a compiled version running quick.&lt;/li&gt;
&lt;li&gt;What about internal arguments? Lets make a static field in a function, and if the language wisely doesn’t support it this behaviour could also be replicated by having a file in which a number is incremented. So now we got a field in that function which number gets incremented on every call, an internal argument not known by the engine. Every function generates the same results with the same arguments but now it doesn’t and for there is no difference between runtime and developtime it would behave unpredictable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Subtext is rather a way to create a function which is ‘instant’, it is a defenition rather than an operation. Computers can’t just do stuff instantly like read a whole file or execute operations.&lt;/p&gt;
&lt;p&gt;I like the idea, but I just see no real practical use.&lt;/p&gt;</description></item><item><title>C&C Generals Scud Hack</title><link>https://blog.affien.com/archives/2005/01/13/cc-generals-scud-hack/</link><pubDate>Thu, 13 Jan 2005 13:57:14 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/13/cc-generals-scud-hack/</guid><description>&lt;p&gt;I’ve found a rather interesting ‘hack’ for C&amp;amp;C generals on a forum: the Scud hack.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Build a Scud Launcher&lt;/li&gt;
&lt;li&gt;Select a unit which can shoot and press Ctrl+1&lt;/li&gt;
&lt;li&gt;Select the Scud Launcher and press Ctrl+2&lt;/li&gt;
&lt;li&gt;Press 1, than press shift+2&lt;/li&gt;
&lt;li&gt;Now you’ve got the Scud launcher and the unit selected. Mouseclick on an area while holding Ctrl to let the unit &lt;strong&gt;and&lt;/strong&gt; the Scud force fire there.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;EA won’t fix the hack but when you use the Scud hack whilst playing a stat-online-game you’re probably get banned.&lt;/p&gt;</description></item><item><title>Chain emails suck & Asia</title><link>https://blog.affien.com/archives/2005/01/10/chain-emails-suck-asia/</link><pubDate>Mon, 10 Jan 2005 20:01:58 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/10/chain-emails-suck-asia/</guid><description>&lt;p&gt;I have received 5 chain emails in my mailbox today claiming that when I forward it to a douzen other people putting my name in it would help the victims of the tsunami in asia.&lt;br&gt;
How? How can miljons of emails help those who most of them haven’t got computers (anymore, or never had) to receive email!&lt;/p&gt;
&lt;p&gt;Usualy people forward one email to 10 others at least, the count on most emails I received was 400. So lets assume that every forwards the email 10 times, and this continues for 400 times:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;10 ** 400 == 1e400&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That are actually more emails than people in the world, usualy people get the same mail back from someone else later in the chain.&lt;/p&gt;
&lt;p&gt;Lets assume that 500 miljon people receive a certain chain mail Ã 100 KB bandwidth for the sender and receiver combined.&lt;/p&gt;
&lt;p&gt;That makes 500 milj times 100 KB is 50 TB..&lt;/p&gt;
&lt;p&gt;1 Gig usualy costs a provider lets say 5 cents: 5 cents times 50 TB is $2500.&lt;/p&gt;
&lt;p&gt;If we would just don’t forward chain mails but all send a simple postcard to asia we would let &lt;strong&gt;them&lt;/strong&gt; show we care and we would save $2500 for the mail providers who will lower prises, which will result in more money for users which eventually results in more money for the world economy including asia!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Never forward a chain mail&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I would like to use this moment to say I am shocked by the tsunami in Asia and I do care for the miljons over there, I hope this single post will convince at least one person to stop forwarding mails, that would save an average of about $100 over some time, my donation for them.&lt;/p&gt;</description></item><item><title>Torrent sharing p2p network</title><link>https://blog.affien.com/archives/2005/01/08/torrent-sharing-p2p-network/</link><pubDate>Sat, 08 Jan 2005 10:55:00 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/08/torrent-sharing-p2p-network/</guid><description>&lt;p&gt;In my &lt;a href="http://blog.w-nz.com/archives/2005/01/06/exeem-the-hype/"&gt;previous post&lt;/a&gt; I discussed Exeem. Exeem is (or actually will be for it hasn’t been launched, just announced) a p2p network for sharing, rating and commenting &lt;em&gt;torrents&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;What is a torrent? A torrent is a small file which is used for the&lt;a href="http://bittorrent.com/introduction.html"&gt;bittorent&lt;/a&gt; p2p file redistribution system to identify a certain file, or files you can download. You first need the torrent for a file/folder before you can download it.&lt;/p&gt;
&lt;p&gt;The major problem with this is that it is impossible to use a bittorent client itself to search for the downloads you want, therefore a lot of sites have been created over time which contain huge searchable collections of torrents. One of these sites was suprnova.org, which has recently been terminated due to legal issues.&lt;/p&gt;
&lt;p&gt;As I elaborated in my &lt;a href="http://blog.w-nz.com/archives/2005/01/06/exeem-the-hype/"&gt;previous post&lt;/a&gt; Exeem probably will suck. So someone will need to do stuff right by making an alternative.&lt;/p&gt;
&lt;p&gt;What issues would have need to be solved to create such a p2p torrent sharing network?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No centralized client list&lt;/strong&gt;, most p2p networks were terminated because they had a centralised tracker to which a client connected to receive the file list and all the users available for a certain file. Instead of a centralised server every single client should tell other clients who else is in the network and what files are there. When giving every client a buildin list of IP’s it can update these by querying these for better IP’s. By rating an IP by uptime and connection bandwidth a big changing group of frequently online users could provide the other IP’s and port search queries for the rest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Searching&lt;/strong&gt;, how to handle a search query? At this moment our client is connected to a few big clients who are frequently online in their neighbourhood, lets call them super nodes for now. When we send them a search query they would look in their cache whether they got the result and if not they look in their own torrents to see whether one of those matched the query and if it doesn’t they’ll just forward it to another a-bit-smaller supernode. The problem with this method is that one query could travel a huge amount of nodes and when you are connected with a good bandwidth you are doing nothing more than passing through queries to other nodes. To solve this the query feedback (when they found a result) should contain the source along with the estamated amount of different search queries the node which had the result can provide. By doing this a shortcut can be formed by one client if it finds a node which either has a lot of files searchable or which has an enourmous cache and offcourse along with that is online often and has a neat bandwidth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rating&lt;/strong&gt; Alongside every torrent you download or expose for upload there would be a meta data file containing a description, rating and comments on the torrent itself. The problem with this system is that descriptions and ratings can change and it is very hard to keep every instance of a torrent on the whole network synchronized. It is possible to send a message through the network to the original node from which you received the file with the new comment message, or you could search for the torrent again by unique id and message the nodes found to have the torrent too. All these methods still include a lot of passing through messages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client side ‘hacking’&lt;/strong&gt;, When everyone would use the default client which automaticly selects super nodes and lets people pass through queries everything will work fine. The big problem is that it is very possible that people would start using illegal client applications which would just leech from the network. To incorpirate methods to get rid of leechers would work when most people are still using the default client, but when people massivly start using illegal clients the network won’t block itself anymore but would certainly get rid off itself for everyone is leeching. This is the major problem that could happen to this p2p network which heavily relies on the fact that everyone should help others whether they like it or not by proxying, caching and passing through various queries to maintain privacy and decentralization.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’d be rather interested in how exeem will address these issues. I guess they would just outrule client site hacking by incorperating various encrypting tricks in their protocol.&lt;/p&gt;</description></item><item><title>Exeem the hype</title><link>https://blog.affien.com/archives/2005/01/06/exeem-the-hype/</link><pubDate>Thu, 06 Jan 2005 19:02:04 +0100</pubDate><guid>https://blog.affien.com/archives/2005/01/06/exeem-the-hype/</guid><description>&lt;p&gt;&lt;a href="http://slashdot.org/article.pl?sid=04/12/30/2311234"&gt;Slashdot on exeem&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since suprnova.org has been offline due to it being illegal the main source for torrents has dissapeared and has lead to a hype around the replacement made by the original maintainers of suprnova, &lt;em&gt;exeem&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;First, what actually was suprnova.org. It was a site which maintained torrents for legal and illegal files. And it did even more; all torrents were thouroughly checked, commented and rated by an enourmous team of editors, making sure that the torrents on Suprnova.org were the best you could possibly find.&lt;/p&gt;
&lt;p&gt;Because Suprnova moderated, commented, rated and checked every single torrent they offered they were without any doubt illegal. If they would have only offered user uploaded torrents with a nice disclaimer that the torrents are the property of their respective owners they would have probably gotten away with it, but they also wouldn’t have got as big as they were.&lt;/p&gt;
&lt;p&gt;Exeem basicly works offers the same as Supernova.org, except that it is a p2p application, not a centralised website.&lt;/p&gt;
&lt;p&gt;It basicly stores torrents and comments on these on a Peer to Peer network similar to Kazaa, which basicly makes every single user of it just as legal instead of just the main servers as it was the case with Supernova’s servers. It is very hard for authorities to punish every single user of a p2p network. There would have to be a trail for every single user which would never be profitable. Governments have tried to confict the big p2p users for this actually is profitable. The main problem is that there aren’t a lot of really big p2p users, just an incredible amount of small users who combined are even worse than a few big ones.&lt;/p&gt;
&lt;p&gt;Exeem sounds great, exeem is an enourmous hype. But I think Exeem will suck:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exeem is p2p, this will most likely cause the rating, comments and moderation on torrents go down a lot and make it less attractive for the user. When having a very secure system so that only a few people can add new torrents to the network you have to have some kind of centralised authority which will be very vulnerable to legal persueds.&lt;/li&gt;
&lt;li&gt;Exeem will be addware, this will cause a lot of people to drop off. Noone wants to have addware on his computer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although I could be mistaking, most hypes like this one tend to turn out really dissapointing.&lt;/p&gt;
&lt;p&gt;In my opinion the only way to get a neat new system like exeem which works cool is to get a p2p torrent redistribution network for legal purposes. Bittorent grew big for it was used to redistribute linux redists. Although it will probably will get used for illegal purposes it just would be a very handy system for legal purposes too.&lt;/p&gt;
&lt;p&gt;More on this later…&lt;/p&gt;</description></item><item><title>Freelancer Binary INI format</title><link>https://blog.affien.com/archives/2004/12/29/freelancer-binary-ini-format/</link><pubDate>Wed, 29 Dec 2004 18:29:23 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/29/freelancer-binary-ini-format/</guid><description>&lt;p&gt;A paper I wrote about the binary INI format used in the game &lt;a href="http://www.microsoft.com/games/freelancer/"&gt;Freelancer&lt;/a&gt; by &lt;a href="http://www.microsoft.com/"&gt;Microsoft&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;gt;&amp;gt;&amp;gt; &lt;a href="http://blog.w-nz.com/uploads/bini.pdf"&gt;Freelancer Binary INI format&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>The dynamic of python</title><link>https://blog.affien.com/archives/2004/12/29/the-dynamic-of-python/</link><pubDate>Wed, 29 Dec 2004 18:21:30 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/29/the-dynamic-of-python/</guid><description>&lt;p&gt;&lt;a href="http://python.org"&gt;Python&lt;/a&gt; is dynamic (duh)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dynamic typing&lt;/strong&gt;&lt;br&gt;
You don’t need to specify the type of an object anywhere.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;def PrintSomething(something):
 print something
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Everything is an object&lt;/strong&gt;&lt;br&gt;
Everything, yes, &lt;strong&gt;everything&lt;/strong&gt; in Python is an object. Even an integer, a method, a class, etc.&lt;br&gt;
Every object has got a type (&lt;code&gt;__class__&lt;/code&gt;), which actually can be changed at runtime, which usually results in conflicts about the allocated size for the &lt;code&gt;PyObject&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No typing needed&lt;/strong&gt;&lt;br&gt;
Python doesn’t know interfaces, for if a certain object wants to expose certain behaviour it just implements the required methods.&lt;br&gt;
When you want a object to be comparible in python you don’t inherit something like &lt;code&gt;IComparible&lt;/code&gt; like in .Net, but you just create the &lt;code&gt;__cmp__&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fields and methods can be changed (and are the same)&lt;/strong&gt;&lt;br&gt;
A method and a field in python are 2 the same things. They both rely in the object’s dictionary (&lt;code&gt;__dict__&lt;/code&gt;) or of the object’s type’s dictionary (&lt;code&gt;__class__.__dict__&lt;/code&gt;).&lt;br&gt;
This allows you to use an object which implements &lt;code&gt;__call__&lt;/code&gt; instead of a method.&lt;br&gt;
For &lt;code&gt;__dict__&lt;/code&gt; is writeable you can change / create &lt;em&gt;attributes&lt;/em&gt; (members) at runtime:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; sys.__dict__[&amp;#39;foo&amp;#39;] = &amp;#34;bar&amp;#34;
&amp;gt;&amp;gt;&amp;gt; sys.foo
&amp;#39;bar&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;A class member function is a normal method, wrapped&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; class exampleclass:
	value = &amp;#34;&amp;#34;
	def examplefunction(self):
		print self.value
&amp;gt;&amp;gt;&amp;gt; def examplereplacement(self):
	print &amp;#34;replacement!&amp;#34;
	print self.value
&amp;gt;&amp;gt;&amp;gt; instance = exampleclass()
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
&amp;gt;&amp;gt;&amp;gt; instance.value = &amp;#34;foobar&amp;#34;
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
foobar
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction = examplereplacement
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
Traceback (most recent call last):
 File &amp;#34;&amp;lt;pyshell#15&amp;gt;&amp;#34;, line 1, in -toplevel-
 instance.examplefunction()
TypeError: examplereplacement() takes exactly 1 argument (0 given)
&amp;gt;&amp;gt;&amp;gt; instance.__class__.examplefunction = examplereplacement
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
Traceback (most recent call last):
 File &amp;#34;&amp;lt;pyshell#17&amp;gt;&amp;#34;, line 1, in -toplevel-
 instance.examplefunction()
TypeError: examplereplacement() takes exactly 1 argument (0 given)
&amp;gt;&amp;gt;&amp;gt; instance.__class__.__dict__[&amp;#39;examplefunction&amp;#39;] = examplereplacement
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
Traceback (most recent call last):
 File &amp;#34;&amp;lt;pyshell#19&amp;gt;&amp;#34;, line 1, in -toplevel-
 instance.examplefunction()
TypeError: examplereplacement() takes exactly 1 argument (0 given)
&amp;gt;&amp;gt;&amp;gt; instance = exampleclass()
&amp;gt;&amp;gt;&amp;gt; instance.__class__.__dict__[&amp;#39;examplefunction&amp;#39;] = examplereplacement
&amp;gt;&amp;gt;&amp;gt; instance.examplefunction()
replacement!
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The bound methods seem to work a bit more tricky than they appear to work. Usually editing member functions via the &lt;code&gt;__class__&lt;/code&gt;‘s &lt;code&gt;__dict__&lt;/code&gt; will result in a proper replacement.&lt;/p&gt;
&lt;p&gt;These were just a few examples of what Python has to offer. These features aren’t limited to Python. &lt;a href="http://www.ironpython.com/"&gt;Iron Python&lt;/a&gt;, an implementation of Python in .Net is capable of letting usual .Net objects to be manipulated in similar ways with Python via Iron Python. Although this doesn’t actually change the .Net objects, changing the wrapper resulting in the required similar behaviour is good enough.&lt;/p&gt;
&lt;p&gt;The author of Iron Python has been recruited by Microsoft and is now working on making the CLR more dynamic.&lt;/p&gt;
&lt;p&gt;I’d love a static dynamic language.&lt;/p&gt;</description></item><item><title>Base64 encoding/decoding algorithm</title><link>https://blog.affien.com/archives/2004/12/27/base64-encodingdecoding-algorithm/</link><pubDate>Mon, 27 Dec 2004 17:58:14 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/27/base64-encodingdecoding-algorithm/</guid><description>&lt;p&gt;I’ve made some python functions to encode/decode &lt;a href="http://www.ietf.org/rfc/rfc2045.txt"&gt;base64&lt;/a&gt;. I’ve been trying to develop my own algorithm for base64 for the &lt;a href="http://blog.w-nz.com/archives/2004/12/22/update-on-the-anti-email-harvester-mailto-links/"&gt;email protection script&lt;/a&gt; which can be found &lt;a href="http://w-nz.com/tools/secureemail.php"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Python again has proved itself again to be a great language for quickly developing stuff.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;def tobase64(s, padd = False):
 b64s = &amp;#34;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&amp;#34;
 b64p = &amp;#34;=&amp;#34;
 ret = &amp;#34;&amp;#34;
 left = 0
 for i in range(0, len(s)):
 if left == 0:
 ret += b64s[ord(s[i]) &amp;gt;&amp;gt; 2]
 left = 2
 else:
 if left == 6:
 ret += b64s[ord(s[i - 1]) &amp;amp; 63]
 ret += b64s[ord(s[i]) &amp;gt;&amp;gt; 2]
 left = 2
 else:
 index1 = ord(s[i - 1]) &amp;amp; (2 ** left - 1)
 index2 = ord(s[i]) &amp;gt;&amp;gt; (left + 2)
 index = (index1 &amp;lt;&amp;lt; (6 - left)) | index2
 ret += b64s[index]
 left += 2
 if left != 0:
 ret += b64s[(ord(s[len(s) - 1]) &amp;amp; (2 ** left - 1)) &amp;lt;&amp;lt; (6 - left)]
 if(padd):
 for i in range(0, (4 - len(ret) % 4) % 4):
 ret += b64p
 return ret
def frombase64(s):
 b64s = &amp;#34;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&amp;#34;
 b64p = &amp;#34;=&amp;#34;
 ret = &amp;#34;&amp;#34;
 s2 = s.replace(b64p, &amp;#34;&amp;#34;)
 left = 0
 for i in range(0, len(s2)):
 if left == 0:
 left = 6
 else:
 value1 = b64s.index(s2[i - 1]) &amp;amp; (2 ** left - 1)
 value2 = b64s.index(s2[i]) &amp;gt;&amp;gt; (left - 2)
 value = (value1 &amp;lt;&amp;lt; (8 - left)) | value2
 ret += chr(value)
 left -= 2
 return ret
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The algorithm doesn’t automaticly add the required &lt;code&gt;=&lt;/code&gt;‘s while encoding, nor does it require while deencoding.&lt;/p&gt;</description></item><item><title>Inactivity</title><link>https://blog.affien.com/archives/2004/12/26/inactivity/</link><pubDate>Sun, 26 Dec 2004 00:09:03 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/26/inactivity/</guid><description>&lt;p&gt;For some undisclosed reasons I won’t be able to access the internet as often as I would like to in the next few weeks. Therefore my activity on the internet will drop, so will the amount of posts on this blog propably. I will try to find some time to post at least 3 articles per week.&lt;/p&gt;
&lt;p&gt;If you want to reach me, try e-mail instead of MSN:&lt;/p&gt;</description></item><item><title>Update on the anti-email-harvester mailto links</title><link>https://blog.affien.com/archives/2004/12/22/update-on-the-anti-email-harvester-mailto-links/</link><pubDate>Wed, 22 Dec 2004 22:50:13 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/22/update-on-the-anti-email-harvester-mailto-links/</guid><description>&lt;p&gt;In the &lt;a href="http://blog.w-nz.com/archives/2004/12/21/protecting-your-email-address-against-spam-bots/"&gt;previous post&lt;/a&gt; I described a simple though effective method to get rid of the constantly cleverer spam email harvester bots.&lt;/p&gt;
&lt;p&gt;I’ve made a little update on the algorithm, it now uses only 1 number for each character and uses a cascading incremental xor transform.&lt;/p&gt;
&lt;p&gt;Python code for the algorithm itself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;def alphaicx(s):
 ret = &amp;#34;&amp;#34;
 cascvalue = 0
 for i in range(0, len(s)):
 ret = ret + chr(ord(s[i]) ^ cascvalue)
 cascvalue = (ord(ret[i]) + 1) % 255 
 return ret
def betaicx(s):
 ret = &amp;#34;&amp;#34;
 cascvalue = 0
 for i in range(0, len(s)):
 ret = ret + chr(ord(s[i]) ^ cascvalue)
 cascvalue = ((ord(ret[i]) ^ cascvalue) + 1) % 255
 return ret
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I designed the algorithm in Python. &lt;a href="http://blog.w-nz.com/archives/2004/12/20/rgb-to-hex-and-why-the-python-interactive-mode-is-so-damned-handy/"&gt;Python is great for that kind of stuff&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As you can see there are 2 functions, when you encode something with &lt;code&gt;alphaicx&lt;/code&gt; you can decode it with &lt;code&gt;betaicx&lt;/code&gt;, and visa versa. &lt;code&gt;betaicx&lt;/code&gt; creates tougher code though. &lt;strong&gt;This &lt;em&gt;encryption&lt;/em&gt; is pretty lousy, but hard enough to stop spam bots&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I’ve ported &lt;code&gt;betaicx&lt;/code&gt; to PHP, and &lt;code&gt;alphaicx&lt;/code&gt; to Javascript. The &lt;a href="http://w-nz.com/tools/secureemail.php?"&gt;running example (very usefull though)&lt;/a&gt; has been updated.&lt;/p&gt;
&lt;p&gt;The PHP/Javascript code for the function:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function JSBotProtect($text){
	$cxred = &amp;#34;0&amp;#34;;
	$cascval = 0;
	for($i = 0; $i &amp;lt; strlen($text); $i++){
		$value = (ord($text[$i]) ^ $cascval);
		$cxred .= &amp;#34;,&amp;#34; . $value;
		$cascval = (($value ^ $cascval) + 1) % 255;
	}
	return &amp;lt;&amp;lt;&amp;lt;EOF
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;var cxred=String.fromCharCode({$cxred});
var uncxred=&amp;#34;&amp;#34;; var cascval=0;for(i=1;i&amp;lt;cxred .length; i++)
{uncxred+=String.fromCharCode(cxred.charCodeAt(i)^cascval);
cascval=((uncxred.charCodeAt(i-1))+1)%255;}document.write(uncxred);&amp;lt;/script&amp;gt;
EOF;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I’ll more compact &lt;code&gt;uncxred&lt;/code&gt; storage. Probable just normal hex, or when I can get it working BASE64.&lt;/p&gt;</description></item><item><title>Protecting your email address against spam bots</title><link>https://blog.affien.com/archives/2004/12/21/protecting-your-email-address-against-spam-bots/</link><pubDate>Tue, 21 Dec 2004 23:43:26 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/21/protecting-your-email-address-against-spam-bots/</guid><description>&lt;p&gt;Spam bots get smarter these days in harvesting email addresses. They usualy use a regex which searches for ‘.. dot .. ltd’, which isn’t that resource intensive. When that is done a more advanced regex is put in there to get the email adress somehow removing stuff like ‘spam’.&lt;/p&gt;
&lt;p&gt;Using normal javascript encoding doesn’t work anymore, for it isn’t that hard for a spider to regognize encoded strings and decode them, whether this is in javascript code or normal html escapes.&lt;/p&gt;
&lt;p&gt;Therefore we need to get more inventive:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function JSBotProtect($text){
	$xorred = &amp;#34;0&amp;#34;;
	$layer = &amp;#34;0&amp;#34;;
	for($i = 0; $i &amp;lt; strlen($text); $i++){
		$layerbit = mt_rand(0, 255);
		$xorred .= &amp;#34;,&amp;#34; . (string)(ord($text[$i]) ^ $layerbit);
		$layer .= &amp;#34;,&amp;#34; . (string)$layerbit;
	}
	return &amp;lt;&amp;lt;&amp;lt;EOF
	&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
		var xorred = String.fromCharCode({$xorred});
		var layer = String.fromCharCode({$layer});
		var unxorred = &amp;#34;&amp;#34;;
		for(i = 1; i &amp;lt; xorred.length; i++){
			unxorred += String.fromCharCode(
				xorred.charCodeAt(i)^layer.charCodeAt(i));
		}
		document.write(unxorred);
	&amp;lt;/script&amp;gt;
EOF;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This PHP function returns a javascript block of code which stores the sensitive string like an email address in 2 parts, which when xorred with eachother result in the original email address.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://w-nz.com/tools/secureemail.php"&gt;An implementation to get a mailto: link&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Developing plugin-based applications</title><link>https://blog.affien.com/archives/2004/12/21/developing-plugin-based-applications/</link><pubDate>Tue, 21 Dec 2004 21:40:40 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/21/developing-plugin-based-applications/</guid><description>&lt;p&gt;When you want to write an application, whether this is a website, or a database manager which is based on plugin provided functionality you should remember two things when programming:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Can I change this behaviour easily with another plugin?&lt;/strong&gt; You want to be able to edit a menu item for instance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do I want to be able to change this with another plugin?&lt;/strong&gt; You don’t want a plugin to edit a menu item if it is meant to only be a simple format interpreter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basicly there are 2 big groups of plugin based applications, the static and dynamic. Where the static plugins are the easiest to program and most commonly used. An example would be a plugin which would load and save an image from and to a ‘.jpg’. These plugins usualy contain one function (gateway) which exposes a few plugins which usualy expose a static interface.&lt;/p&gt;
&lt;p&gt;On the other side there are the over-dynamic plugins, which rather should be called ‘modules’. These applications would use a high level slow ‘message’ system where basicly everything is able to be intercepted, hooked up to, responded to…&lt;/p&gt;
&lt;p&gt;Deciding what and how you want base behaviour to be able to be extended, edited or removed by plugins is the hardest part of developing a plugin based application. If everything should be able to be changed you get stuck with complicated code, and a lot of overhead due to extra ‘hookable’ calls. If almost nothing is overridable you problably get stuck with worthless plugins.&lt;/p&gt;
&lt;p&gt;While developing a plugin extendable application it is very helpfull to put the base code in several plugins themselves, which prevents a lot of mistakes.&lt;/p&gt;
&lt;p&gt;I’ve found python and c# to be very capable languages to write plugins, although C# is a bit more trouble than Python, Python allows you to do too much and just call functions without knowing for sure with what object you are handling.&lt;/p&gt;
&lt;p&gt;I’ve been working on a modular server (see &lt;a href="http://blog.w-nz.com/archives/2004/12/11/modular-server/"&gt;the modular server article&lt;/a&gt; I’ve posted), programmed in C#.&lt;/p&gt;
&lt;p&gt;The base of the server is nothing more than a framework for loading / unloading libraries &amp;amp; plugins, managing configuration files, and hosting ‘server’ plugin instances. Every server plugin itself can load plugins (like for instance a custom authentication handler for a HTTP server). I’ve noticed that having a very dynamic configuration storage is very usefull for every instance of a plugin requires its own configurations and usualy its own plugins to be loaded. I’m currently using multiple tree based files which are merged at runtime, which I’ll replace with a concept format called XTL about which I’ll tell more lateron.&lt;/p&gt;</description></item><item><title>RGB to Hex (and why the python interactive mode is so damned handy)</title><link>https://blog.affien.com/archives/2004/12/20/rgb-to-hex-and-why-the-python-interactive-mode-is-so-damned-handy/</link><pubDate>Mon, 20 Dec 2004 00:18:52 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/20/rgb-to-hex-and-why-the-python-interactive-mode-is-so-damned-handy/</guid><description>&lt;p&gt;&lt;ins&gt;Update 2010-02-01&lt;/ins&gt; Thanks to Sameer for pointing out the short way of doing this: &lt;code&gt;return “#%02X%02X%02X” % (r,g,b)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;def tohex(r,g,b):
	hexchars = &amp;#34;0123456789ABCDEF&amp;#34;
	return &amp;#34;#&amp;#34; + hexchars[r / 16] + hexchars[r % 16] + hexchars[g / 16] + hexchars[g % 16] + hexchars[b / 16] + hexchars[b % 16]
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://python.org"&gt;Python&lt;/a&gt; is very convenient when you need to program a simple algorithm. I programmed this RGB to Hex converter in less than 1 minute, including using the function for a few RGB values I needed to convert.&lt;/p&gt;
&lt;p&gt;Usualy I just grab a pen and a paper and do the calculations myself for getting either the calculator of windows itself to show up and actually calculate stuff properly (looking to screen, writing down, forgetting to press C, starting again…), or writing a program in a language like C# would just take too much time.&lt;/p&gt;
&lt;p&gt;I’ve been using Idle for quite some time as a very good replacement for both my calculator and my pen and paper.&lt;/p&gt;</description></item><item><title>Markup? Nah, wysiwyg!</title><link>https://blog.affien.com/archives/2004/12/18/markup-nah-wysiwyg/</link><pubDate>Sat, 18 Dec 2004 19:06:10 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/18/markup-nah-wysiwyg/</guid><description>&lt;p&gt;When you post something on a forum, on a guestbook, on anything on the web which supports some kind of formatting of your code it works with some sort of &lt;a href="http://www.phpbb.com/phpBB/faq.php?mode=bbcode"&gt;BB-Code&lt;/a&gt;.&lt;br&gt;
BB-Code is just like HTML formatting, with ‘[]’s instead of ‘&amp;lt;&amp;gt;‘s, and a lot less features. It is hard to type and doesn’t look neat.&lt;/p&gt;
&lt;p&gt;But who cares? Everyone uses BB-Code, almost everyone knows BB-Code, and most people don’t find it hard to type for people are just too used to it!&lt;/p&gt;
&lt;p&gt;There are alternatives to BB-Code, like &lt;a href="http://textism.com/tools/textile/"&gt;Textile&lt;/a&gt; and &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt;, which use a more convenient syntax.&lt;br&gt;
Personally I don’t like using them for I ain’t used to the syntax.&lt;/p&gt;
&lt;p&gt;However.. why would we want to &lt;em&gt;write&lt;/em&gt; formating anyway? Why not just use wysiwyg, and I do not mean a java applet but rather a standard for browsers; a new tag: “&lt;code&gt;&amp;lt;input type=&amp;quot;formatted&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;/code&gt;“, which would act for the server as a normal input field returning the formatted text in Html.&lt;/p&gt;
&lt;p&gt;The problem is that it would be very hard to get every browser to support such a new tag. Most browsers I guess would be very willing to comply. But browsers like for instance Internet Explorer wouldn’t. They don’t even comply with the simplest of CSS at the moment which gives website developers a headache.&lt;/p&gt;</description></item><item><title>Intrepid C – ‘Objects’ in C</title><link>https://blog.affien.com/archives/2004/12/16/intrepid-c-objects-in-c/</link><pubDate>Thu, 16 Dec 2004 23:35:19 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/16/intrepid-c-objects-in-c/</guid><description>&lt;p&gt;I’m working on a library which can be used to achieve most OOP functionality of OO languages in C, by providing an API (not by extending the syntax).&lt;/p&gt;
&lt;p&gt;I’ve written 2 articles (&lt;a href="http://blog.w-nz.com/archives/2004/12/14/objects-in-c/"&gt;artc. 1&lt;/a&gt;, &lt;a href="http://blog.w-nz.com/archives/2004/12/15/objects-in-c-2/"&gt;artc. 2&lt;/a&gt;) so far about getting OO like behaviour in C, and will write a few more about the more advanced stuff which I’m still experimenting with.&lt;/p&gt;
&lt;p&gt;You can download the source of the API I have developed so far &lt;a href="http://blog.w-nz.com/uploads/cobject161204.zip"&gt;here&lt;/a&gt;, which by the way is far from finished. Stuff will change, and I am aware of some issues.&lt;/p&gt;
&lt;p&gt;I’ll explain how it works in the next parts in the ‘Objects in C’ serie, but to give you a kickstart in the code I’ll explain it briefly:&lt;/p&gt;
&lt;p&gt;Every object has got a pointer to its type and its toplevel object, which usualy is itself. The type instance pointed to from the instance provides the size, constructor, destructor and the interfacegetter.&lt;br&gt;
The &lt;code&gt;GetInterface&lt;/code&gt; function in the type (the interfacegetter) returns a pointer to an instance of an object of the given type if supported by the object.&lt;br&gt;
Using interfaces can serve different purposes:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exposing certain objectwide functionality&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;((ICloneable*)object-&amp;gt;top-&amp;gt;type-&amp;gt;GetInterface(object-&amp;gt;top-&amp;gt;type, object-&amp;gt;top, GetICloneableType()))-&amp;gt;Clone(object-&amp;gt;top);&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This code will return a Clone of the &lt;code&gt;object&lt;/code&gt;, even if only the object is passed by a not top level pointer. Using the &lt;code&gt;top&lt;/code&gt; pointer ensures proper polyforism, and enables the ability for the top most class to hide, or show some internal functionality of wrapped objects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exposing interface specific functionality&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;((String*)object-&amp;gt;type-&amp;gt;GetInterface(object-&amp;gt;type, object, GetIToStringAble()))-&amp;gt;ToString(object);&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It now depends on which interface of a certain object is passed which behaviour results.&lt;/p&gt;
&lt;p&gt;And more.. and more.. which I will explain in the coming articles.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.w-nz.com/uploads/cobject161204.zip"&gt;Download the source so far&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Some more on my blog</title><link>https://blog.affien.com/archives/2004/12/16/some-more-on-my-blog/</link><pubDate>Thu, 16 Dec 2004 23:02:28 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/16/some-more-on-my-blog/</guid><description>&lt;p&gt;I’m keeping this blog mainly to channel some thoughts about computer science (but probably about physics and other subjects which I find interesting too). I hope people will find the stuff I’ll write about interesting, and hopefully usefull. Most stuff I’ll post will as far as I know be quite new, or a new approach to an existing issue.&lt;/p&gt;
&lt;p&gt;It seems that so far 3 people have linked to an article on this blog (all of them to the &lt;a href="http://blog.w-nz.com/archives/2004/12/14/objects-in-c/"&gt;Objects in C article&lt;/a&gt;) already. (Thanks! without readers a webblog is quite useless!)&lt;/p&gt;</description></item><item><title>‘Objects’ in C – part 2, ‘type’ing stuff</title><link>https://blog.affien.com/archives/2004/12/15/objects-in-c-2/</link><pubDate>Wed, 15 Dec 2004 20:32:49 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/15/objects-in-c-2/</guid><description>&lt;p&gt;In my &lt;a href="http://blog.w-nz.com/archives/2004/12/14/objects-in-c/"&gt;previous article&lt;/a&gt; I’ve talked about the basics of using ‘object like’ programming in C. Actually they rather were more like examples. To continue further I’ll discuss the stuff behind it more detailed, but first I’ll explain the basics of structs, if you know them already, just skip that part of this part.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Structs in C (and in the memory)&lt;/strong&gt;&lt;br&gt;
An example structure in C:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;struct example{int a; int b;};&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;A structure is nothing more than a way of giving some parts in a fixed size amount of memory a specific name, and a recommended type.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When one would create a new instance of the example structure it would require 8 bytes of space in the memory, 4 for &lt;code&gt;a&lt;/code&gt;, the first integer and again 4 bytes for &lt;code&gt;b&lt;/code&gt;, the second integer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;00 a&lt;br/&gt;
01 a&lt;br/&gt;
02 a&lt;br/&gt;
03 a&lt;br/&gt;
04 a&lt;br/&gt;
05 b&lt;br/&gt;
06 b&lt;br/&gt;
07 b&lt;br/&gt;
08 b&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An instance of the example struct could begin at the memory address&lt;code&gt;0x0A001000&lt;/code&gt;. In that case the value of &lt;code&gt;a&lt;/code&gt; would be at the memory adress &lt;code&gt;0x0A001000&lt;/code&gt; too, for &lt;code&gt;a&lt;/code&gt; is the first &lt;em&gt;field&lt;/em&gt; in the structure. The value of &lt;code&gt;b&lt;/code&gt; however would be located at &lt;code&gt;0x0A00100&lt;strong&gt;4&lt;/strong&gt;&lt;/code&gt; for &lt;code&gt;b&lt;/code&gt; is the second field and is located 4 bytes after the start of the structure. I could use that knowladge to access &lt;code&gt;b&lt;/code&gt; in several different ways:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;example* e = malloc(sizeof(example)); e-&amp;gt;a = 1; e-&amp;gt;b = 10;&lt;br/&gt;
printf(&amp;quot;%d&amp;quot;, e-&amp;gt;b); // The usual way&lt;br/&gt;
printf(&amp;quot;%d&amp;quot;, *((int*)((int)e + 4)); // Converts e to an integer, adds 4 and then interprets the result as a pointer to an integer&lt;br/&gt;
printf(&amp;quot;%d&amp;quot;, *((int*)((int)(&amp;amp;(e-&amp;gt;a)) + 4)); // Basicly the same way, but now via 'a' which is at the offset of the struct anyway&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Structure inheritance&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef struct {
	int a; 
	int b; 
	int result;
} SumHandle;
void GetResult(SumHandle* handle){
	handle-&amp;gt;result = handle-&amp;gt;a + handle-&amp;gt;b;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The example &lt;code&gt;SumHandle&lt;/code&gt; struct is a very simple (and useless) structure to store 2 operands, and the result which is filled by calling the &lt;code&gt;GetResult&lt;/code&gt; function providing a pointer to the handle.&lt;/p&gt;
&lt;p&gt;This works fine, but we could want to add more functionality, for instance why not want to know the result of multiplying those 2 operands? We could make a new struct defenition and a new &lt;code&gt;GetResult&lt;/code&gt; function which still uses the old &lt;code&gt;GetResult&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef struct {
	int a; 
	int b; 
	int sumResult;
	int multResult;
} SumHandle2;
void GetResult2(SumHandle2* handle){
	handle-&amp;gt;multResult = handle-&amp;gt;a * handle-&amp;gt;b;
	GetResult((SumHandle*)handle);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;As you can see changing the name of the originaly named &lt;code&gt;result&lt;/code&gt; field hasn’t got any effect for only the offset from the offset from the struct offset is used at runtime, therefore I could add the extra field and still use the original &lt;code&gt;GetResult&lt;/code&gt; function. This can be done for the original &lt;code&gt;GetResult&lt;/code&gt; function only uses the first 12 bytes of the pointed to piece of memory. Adding stuff after that does not effect the original function. Note that the oposite is not possible for changing memory outside your own allocated memory could do really nasty stuff causing the all-too-known &lt;abbr title="General Protection Faults"&gt;GPF&lt;/abbr&gt;‘s.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Virtual functions&lt;/strong&gt;&lt;br&gt;
In the previous example only an extension has been made to the original behaviour. To overwrite the previous behaviour you need to use virtual functions to overwrite the previous call, the original struct would look like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef void (*GetResultHandler)(void* result);
typedef struct {
	int a; 
	int b; 
	int result;
	GetResultHandler GetResult;
} SumHandle;
void GetResultImpl(void* handle){
	((SumHandle*)handle)-&amp;gt;result = ((SumHandle*)handle)-&amp;gt;a + ((SumHandle*)handle)-&amp;gt;b;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;GetResult&lt;/code&gt; field is a function pointer which would be set in an initialization function of &lt;code&gt;SumHandle&lt;/code&gt; to the &lt;code&gt;GetResultImpl&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;Overwriting the behaviour would be as simple as writing a new initialization function used which would use another &lt;code&gt;GetResult&lt;/code&gt; implementation. This for calling &lt;code&gt;resultHandleInstance-&amp;gt;GetResult(resultHandleInstance)&lt;/code&gt; is nothing more than calling the function at the address specified in the &lt;code&gt;GetResult&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A type&lt;/strong&gt;&lt;br&gt;
Every inheritance at the moment still needs a custom constructor and destructor function. Therefore some functionality could not be ashieved like making a copy of a handle for that would need both the constructor function and the actual size of the struct, which both aren’t available when only a pointer is passed. Possibly a custom clone function would need to be provided.&lt;br&gt;
If every object would expose a pointer to a type struct containing information about the struct this problem would be eliminated:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#include &amp;lt;malloc.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
// Default defenitions
typedef struct _Type	Type;
typedef struct _Object	Object;
typedef void (*ConstructorHandler)	(Type* type, Object* instance);
typedef void (*DestructorHandler)	(Type* type, Object* instance);
struct _Type {
	int					size;
	ConstructorHandler	Construct;
	DestructorHandler	Destruct;
};
struct _Object {
	Type*				type;
};
Object* Construct(Type* type) {
	Object* object	= malloc(type-&amp;gt;size);
	object-&amp;gt;type	= type;
	type-&amp;gt;Construct(type, object);
	return object;
}
void Destruct(Object* object) {
	object-&amp;gt;type-&amp;gt;Destruct(object-&amp;gt;type, object);
	free(object);
}
Type* CreateType(int size, ConstructorHandler constructor, DestructorHandler destructor) {
	Type* type		= malloc(sizeof(Type));
	type-&amp;gt;size		= size;
	type-&amp;gt;Construct	= constructor;
	type-&amp;gt;Destruct	= destructor;
	return type;
}
// An example implementation
typedef struct _Example Example;
typedef void (*GenerateResultHandler)(Example* example);
struct _Example {
	Type*					type;
	int						a;
	int						b;
	int						result;
	GenerateResultHandler	GenerateResult;
};
void GenerateResultImpl(Example* example) {
	example-&amp;gt;result = example-&amp;gt;a + example-&amp;gt;b;
}
void ConstructExample (Type* type, Object* instance) {
	((Example*)instance)-&amp;gt;a					= 0;
	((Example*)instance)-&amp;gt;b					= 0;
	((Example*)instance)-&amp;gt;result			= 0;
	((Example*)instance)-&amp;gt;GenerateResult	= GenerateResultImpl;
}
void DestructExample (Type* type, Object* instance) {
}
Type* CreateExampleType() {
	return CreateType(sizeof(Example), ConstructExample, DestructExample); 
}
void main() {
	Type* exampleType = CreateExampleType();
	Example* example = (Example*)Construct(exampleType);
	example-&amp;gt;a = 5;
	example-&amp;gt;b = 5;
	example-&amp;gt;GenerateResult(example);
	printf(&amp;#34;%d&amp;#34;, example-&amp;gt;result);
	Destruct((void*)example);
	getchar();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;To add an inheritance:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#include &amp;lt;malloc.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
// Default defenitions
typedef struct _Type	Type;
typedef struct _Object	Object;
typedef void (*ConstructorHandler)	(Type* type, Object* instance);
typedef void (*DestructorHandler)	(Type* type, Object* instance);
struct _Type {
	int					size;
	ConstructorHandler	Construct;
	DestructorHandler	Destruct;
};
struct _Object {
	Type*				type;
};
Object* Construct(Type* type) {
	Object* object	= malloc(type-&amp;gt;size);
	object-&amp;gt;type	= type;
	type-&amp;gt;Construct(type, object);
	return object;
}
void Destruct(Object* object) {
	object-&amp;gt;type-&amp;gt;Destruct(object-&amp;gt;type, object);
	free(object);
}
Type* CreateType(int size, ConstructorHandler constructor, DestructorHandler destructor) {
	Type* type		= malloc(sizeof(Type));
	type-&amp;gt;size		= size;
	type-&amp;gt;Construct	= constructor;
	type-&amp;gt;Destruct	= destructor;
	return type;
}
// An example implementation
typedef struct _Example Example;
typedef void (*GenerateResultHandler)(Example* example);
struct _Example {
	Type*					type;
	int						a;
	int						b;
	int						result;
	GenerateResultHandler	GenerateResult;
};
void GenerateResultImpl(Example* example) {
	example-&amp;gt;result = example-&amp;gt;a + example-&amp;gt;b;
}
void ConstructExample (Type* type, Object* instance) {
	((Example*)instance)-&amp;gt;a					= 0;
	((Example*)instance)-&amp;gt;b					= 0;
	((Example*)instance)-&amp;gt;result			= 0;
	((Example*)instance)-&amp;gt;GenerateResult	= GenerateResultImpl;
}
void DestructExample (Type* type, Object* instance) {
}
Type* CreateExampleType() {
	return CreateType(sizeof(Example), ConstructExample, DestructExample); 
}
// An inheritance
typedef struct _Example2 Example2;
typedef void (*GenerateResult2Handler)(Example2* example);
struct _Example2 {
	Type*					type;
	int						a;
	int						b;
	int						result;
	GenerateResult2Handler	GenerateResult;
	int						result2;
};
void GenerateResult2Impl(Example2* example) {
	example-&amp;gt;result = example-&amp;gt;a * example-&amp;gt;b;
	example-&amp;gt;result2 = example-&amp;gt;a + example-&amp;gt;b;
}
void ConstructExample2 (Type* type, Object* instance) {
	((Example2*)instance)-&amp;gt;a				= 0;
	((Example2*)instance)-&amp;gt;b				= 0;
	((Example2*)instance)-&amp;gt;result			= 0;
	((Example2*)instance)-&amp;gt;result2			= 0;
	((Example2*)instance)-&amp;gt;GenerateResult	= GenerateResult2Impl;
}
void DestructExample2 (Type* type, Object* instance) {
}
Type* CreateExampleType2() {
	return CreateType(sizeof(Example2), ConstructExample2, DestructExample2); 
}
void main() {
	Type* exampleType = CreateExampleType();
	Type* example2Type = CreateExampleType2();
	Example* example = (Example*)Construct(exampleType);
	Example2* example2 = (Example2*)Construct(example2Type);
	example-&amp;gt;a = 5;	example-&amp;gt;b = 5;
	example2-&amp;gt;a = 5;	example2-&amp;gt;b = 5;
	example-&amp;gt;GenerateResult(example);
	example2-&amp;gt;GenerateResult(example2);
	printf(&amp;#34;example: result: %dn&amp;#34;, example-&amp;gt;result);
	printf(&amp;#34;example2: result: %d result2: %dn&amp;#34;, example2-&amp;gt;result, example2-&amp;gt;result2);
	Destruct((void*)example);
	Destruct((void*)example2);
	getchar();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;br&gt;
Although using types, and casts creates a lot more freedom, it still has its limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No multi inheritance possible&lt;/li&gt;
&lt;li&gt;No ‘new’ functions (functions that are only used when a pointer is specificly cast to a struct)&lt;/li&gt;
&lt;li&gt;No static support throughout types&lt;/li&gt;
&lt;li&gt;No type behaviour inheritance (a type still has its own basetype and isn’t an object itself)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll explain some stuff about wrapping old implementations, or even multiple implementations in the next part, which will overcome these limitations.&lt;/p&gt;</description></item><item><title>‘Objects’ in C – part 1, the basics</title><link>https://blog.affien.com/archives/2004/12/14/objects-in-c/</link><pubDate>Tue, 14 Dec 2004 23:20:30 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/14/objects-in-c/</guid><description>&lt;p&gt;(&lt;a href="http://blog.w-nz.com/archives/2004/12/15/objects-in-c-2/"&gt;Next part&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;C is on memory allocation quite faster than C++ for C++ contains a lot of overhead due to its object orientated nature.&lt;br&gt;
Although not as convenient in C it is possible to get ‘Object’ like stuff in C as in C++.&lt;/p&gt;
&lt;p&gt;I’ll explain the basics in this first part, and continue with more complicated (and neater stuff) in the later parts. I hope you’ll find them usefull.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The base&lt;/strong&gt;&lt;br&gt;
For this example we’ll use a ‘class’ called ‘example’, first the base:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef struct{
	int dummy;
} Example;
Example* ConstructExample(){
	return malloc(sizeof(Example));
}
void DestructExample(Example* example){
	free(example);
}
void main(){
	Example* e;
	e = ConstructExample();
	DestructExample(e);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Simple inheritance&lt;/strong&gt;&lt;br&gt;
Lets add some values, and some simple functions and inheritance. Using the inherited class as the base class is just a simple matter of casting via &lt;code&gt;void*&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef struct {
	int a;
} Example;
typedef struct {
	int a;
	int b;
} Example2;
Example2* ConstructExample2() {
	Example2* example = malloc(sizeof(Example2));
	example-&amp;gt;b = 10;
	example-&amp;gt;a = 11;
	return example;
}
Example* ConstructExample() {
	Example* example = malloc(sizeof(Example));
	example-&amp;gt;a = 1;
	return example;
}
void DestructExample(Example* example) {
	free(example);
}
void DestructExample2(Example2* example) {
	free(example);
}
void PrintExample(Example* example) {
	printf(&amp;#34;%d &amp;#34;, example-&amp;gt;a);
}
void PrintExample2(Example2* example) {
	printf(&amp;#34;%d &amp;#34;, example-&amp;gt;b);
}
void main() {
	Example* e;
	Example2* e2;
	e = ConstructExample();
	e2 = ConstructExample2();
	PrintExample((void*)e);
	PrintExample((void*)e2);
	PrintExample2((void*)e2);
	DestructExample(e);
	DestructExample2(e2);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;When inheriting you have to copy the original defenition and only append at the bottom, changing nothing of the previous stuff for otherwise you’ll get nasty errors. When you want to override stuff you got to use neat tricks, more on that lateron.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Virtual functions&lt;/strong&gt;&lt;br&gt;
Using function pointers, virtual functions can be used:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;typedef void (*PrintExample)(void* example);
typedef struct {
	int a;
	PrintExample Print;
} Example;
typedef struct {
	int a;
	PrintExample Print;
	int b;
} Example2;
void PrintExampleImpl(void* example) {
	printf(&amp;#34;(printexample) %d&amp;#34;, ((Example*)example)-&amp;gt;a);
}
void PrintExample2Impl(void* example) {
	printf(&amp;#34;(printexample2) %d &amp;#34;, ((Example2*)example)-&amp;gt;b);
	PrintExampleImpl(example);
}
Example2* ConstructExample2() {
	Example2* example = malloc(sizeof(Example2));
	example-&amp;gt;b = 10;
	example-&amp;gt;a = 11;
	example-&amp;gt;Print = PrintExample2Impl;
	return example;
}
Example* ConstructExample() {
	Example* example = malloc(sizeof(Example));
	example-&amp;gt;a = 1;
	example-&amp;gt;Print = PrintExampleImpl;
	return example;
}
void DestructExample(Example* example) {
	free(example);
}
void DestructExample2(Example2* example) {
	free(example);
}
void main() {
	Example* e;
	Example2* e2;
	e = ConstructExample();
	e2 = ConstructExample2();
	e-&amp;gt;Print(e);
	e2-&amp;gt;Print(e2);
	DestructExample(e);
	DestructExample2(e2);
	getchar();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;A virtual function still has to be supplied with the function in which it has been called. 2 simple macro can be made to make a &lt;em&gt;this call&lt;/em&gt; a bit easier, (for some :p):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;#define THISCALLPAR(x,y,z) x-&amp;gt;y(x,z)&lt;br/&gt;
#define THISCALL(x,y) x-&amp;gt;y(x)&lt;br/&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wrapped inheritance&lt;/strong&gt;&lt;br&gt;
To override some functionality and retain other functionality while adding your own functionality is virtually impossible by using one simple object. &lt;em&gt;Multi-inheritance&lt;/em&gt; would be virtually impossible.&lt;br&gt;
2 parts ahead I will talk about these limitations and how to overcome them, the &lt;a href="http://blog.w-nz.com/archives/2004/12/15/objects-in-c-2/"&gt;next part&lt;/a&gt; discusses inheritance in more detail, and adding ‘Types’ in the mix.&lt;/p&gt;</description></item><item><title>Intrepid.IO.FragmentedStream</title><link>https://blog.affien.com/archives/2004/12/14/intrepidiofragmentedstream/</link><pubDate>Tue, 14 Dec 2004 19:30:13 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/14/intrepidiofragmentedstream/</guid><description>&lt;p&gt;While working on a design of a .pak files, which are nothing more then archives, I noticed most existing .pak files are just very simple. This for they put all files after eachother which makes it really hard to even just add a file, or delete one.&lt;/p&gt;
&lt;p&gt;Therefor I started thinking about a way to make an efficient archive file for read and write access.&lt;/p&gt;
&lt;p&gt;There are basicly 2 ways to accomplish this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clustering&lt;/li&gt;
&lt;li&gt;Fragmenting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Fragmenting&lt;/strong&gt;.&lt;br&gt;
The archive consists out of several files, and an index which is counted as a file. The start of every file is pointed to from the index by its offset. When a file is deleted, its record in the index is null-ed, which is lateron filled with a new entry and in the meantime ignored (for the only file that can start at position 0 is the index itself).&lt;/p&gt;
&lt;p&gt;A file itself is fragmented, every fragment starts with 4 bytes marking the length of the fragment and after that again 4 bytes marking the offset of the next fragment this time. In case there is no next fragment present the next-cluster-offset is 0. The first fragment of every file contains after the 8 bytes marking the length and offset of the next fragment some information about the file like the name.&lt;/p&gt;
&lt;p&gt;For the index itself is a file, it also is fragmented and can grow, and shrink.&lt;/p&gt;
&lt;p&gt;The 4 byte offset value could be default set to 8 bytes in case files are going to be bigger than 2 Gig, and the oposite in case you are dealing with small files. Although this can decrease the size of files which are frequently edited it isn’t possible to increase or decrease to 8 or 2 bytes in runtime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Clustered&lt;/strong&gt;&lt;br&gt;
The clustered way is practicly the same as the fragmented way except for that every fragment is padded to a multiple of the cluster size. Therefore the ‘next fragment’ value can now be a cluster number instead of an offset. This will both increase the speed of writing due to having always a buffer, also defragmenting will be faster. The files itself will also be able to retain a 2 byte next-cluster pointer longer. The only downside is that files will just be larger.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FragmentedStream&lt;/strong&gt;&lt;br&gt;
The fragmented stream wraps these methods pretty efficiently at the moment.&lt;br&gt;
I am thinking to implement an inteligent algorithm which checks which streams are often used which are then placed at the end of the file with a buffer. This also could be applied for files which are marked to be expanding.&lt;/p&gt;</description></item><item><title>Rich Client Side Framework</title><link>https://blog.affien.com/archives/2004/12/14/rich-client-side-framework/</link><pubDate>Tue, 14 Dec 2004 17:13:00 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/14/rich-client-side-framework/</guid><description>&lt;p&gt;On several blogs the idea of having a rich java script passed, for example on &lt;a href="http://www.zefhemel.com/archives/2004/12/12/rich-web-ui"&gt;ZefHemel.com: Rich Web UI: Search As You Type&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Guess due to google, which has made a neat &lt;a href="http://gmail.google.com/gmail"&gt;Webmail interface for gmail&lt;/a&gt; and &lt;a href="http://www.google.com/webhp?complete=1&amp;amp;hl=en"&gt;Google suggest&lt;/a&gt; with find as you type.&lt;/p&gt;
&lt;p&gt;The demands on java script keeps growing. People want to make better webUI’s and features with Javascript although javascript is defenitely not designed for this stuff.&lt;/p&gt;
&lt;p&gt;Using flash, and java is an overkill, but using javascript is espacially an overkill for javascript isnt handled consistantly on different browsers, and isn’t as quick and maintainable as it could be.&lt;/p&gt;
&lt;p&gt;I guess it would be time to extend HTML itself with a more advanced script; java like preferably although then directly supported by the browser, and less aimed at custom drawing but using an API provided by the browser.&lt;/p&gt;
&lt;p&gt;I’m currently experimenting with Microsoft .net assemblies which are downloaded in slimmed form as webpage which are executed with very limited access. Which works neat although it is still an overkill (a .dll is about 20 Kb, even if you got only one line of code..)&lt;/p&gt;
&lt;p&gt;Just a thought.&lt;/p&gt;</description></item><item><title>OO Stated Stackbased Parsing</title><link>https://blog.affien.com/archives/2004/12/12/oo-stated-stackbased-parsing/</link><pubDate>Sun, 12 Dec 2004 13:25:29 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/12/oo-stated-stackbased-parsing/</guid><description>&lt;p&gt;Every parsable format (like INI, XML) consists out of certain area’s. You can be parsing the section name at one moment, or be parsing a comment when parsing an INI. These certain area’s where you can parse result in a &lt;strong&gt;parse state&lt;/strong&gt;. In every state you expect something else, and you gather other kinds of information.&lt;/p&gt;
&lt;p&gt;When you are parsing in a certain state you can find that the state has changed (the parser found a new xml node in a xml file), then the old state is pushed on the &lt;strong&gt;state stack&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In certain circumstances you need to have the ability to fall back to a previous state, this can happen when you are parsing a apparently new section name and suddenly there is a comment character instead of a sectionname end character. In this case you need to be able to fall back on the previous section you were parsing. Although when you successfully have parsed the sectionname you want the old sectionstate removed from the stack (and the data of it emited).&lt;br&gt;
&lt;br&gt;
An example of a &lt;strong&gt;state based&lt;/strong&gt; parser is this INI parser I wrote in C#:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
 public override void Load(Stream stream)
 {
 StreamReader sr = new StreamReader(stream);
 Stack&amp;lt;parsestate&amp;gt; stack = new Stack&amp;lt;parsestate&amp;gt;();
 stack.Push(ParseState.NoSection);
 StringBuilder sb = null;
 IniSection section = null;
 IniEntry entry = null;
 while (true)
 {
 char c = (char)sr.Read();
 ParseState s = stack.Peek();
 if (s == ParseState.NoSection)
 {
 if (c == 32 || c == 9 || c == 10 || c == 13)
 {
 // To nothing.
 }
 else if (c == &amp;#39;[&amp;#39;)
 {
 stack.Push(ParseState.SectionName);
 sb = new StringBuilder();
 }
 else
 {
 stack.Push(ParseState.TillNewLine);
 }
 }
 else if (s == ParseState.TillNewLine)
 {
 if (c == 13 || c == 10)
 {
 stack.Pop();
 }
 }
 else if (s == ParseState.SectionName)
 {
 if (c == 13 || c == 10)
 {
 stack.Pop();
 }
 else if (c == &amp;#39;]&amp;#39;)
 {
 stack.Clear();
 stack.Push(ParseState.EntryName);
 stack.Push(ParseState.TillNewLine);
 _Sections.Add(section = new IniSection(sb.ToString()));
 sb = new StringBuilder();
 }
 else if (c == &amp;#39;;&amp;#39;)
 {
 stack.Pop();
 stack.Push(ParseState.TillNewLine);
 }
 else
 {
 sb.Append( c );
 }
 }
 else if (s == ParseState.EntryName)
 {
 if (c == 13 || c == 10)
 {
 string result = sb.ToString().Trim();
 if (result != &amp;#34;&amp;#34;)
 {
 section.Entries.Add(new IniEntry(result));
 }
 sb = new StringBuilder();
 }
 else if (c == &amp;#39;;&amp;#39;)
 {
 string result = sb.ToString().Trim();
 if (result != &amp;#34;&amp;#34;)
 {
 section.Entries.Add(new IniEntry(result));
 }
 stack.Push(ParseState.TillNewLine);
 sb = new StringBuilder();
 }
 else if (c == &amp;#39;=&amp;#39;)
 {
 section.Entries.Add(entry = new IniEntry(sb.ToString().Trim()));
 stack.Push(ParseState.EntryValue);
 sb = new StringBuilder();
 }
 else if (c == &amp;#39;[&amp;#39;)
 {
 if (sb.ToString().Trim() == &amp;#34;&amp;#34;)
 {
 stack.Push(ParseState.SectionName);
 sb = new StringBuilder();
 }
 else
 {
 sb.Append( c );
 }
 }
 else
 {
 sb.Append( c );
 }
 }
 else if (s == ParseState.EntryValue)
 {
 if (c == &amp;#39;;&amp;#39;)
 {
 entry.Values.Add(new TextIniValue(sb.ToString().Trim()));
 sb = new StringBuilder();
 stack.Pop();
 stack.Push(ParseState.EntryName);
 stack.Push(ParseState.TillNewLine);
 }
 else if (c == 10 || c == 13)
 {
 entry.Values.Add(new TextIniValue(sb.ToString().Trim()));

 sb = new StringBuilder();
 stack.Pop();
 stack.Push(ParseState.EntryName);
 }
 else if (c == &amp;#39;,&amp;#39;)
 {
 entry.Values.Add(new TextIniValue(sb.ToString().Trim()));
 sb = new StringBuilder();
 }
 else
 {
 sb.Append( c );
 }
 }
 }
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I am now investigating whether creating a more Object Orientated implementation would be feasible, and even more importantly whether with this technique it would be possible to write a state description file which the parser reads, and just produces the data which is meant to be captured as described in the state description file.&lt;/p&gt;</description></item><item><title>Parsing $_SERVER[‘PATH_INFO’]</title><link>https://blog.affien.com/archives/2004/12/12/parsing-_serverpath_info/</link><pubDate>Sun, 12 Dec 2004 12:20:34 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/12/parsing-_serverpath_info/</guid><description>&lt;p&gt;The PHP global variable &lt;code&gt;$_SERVER['PATH_INFO']&lt;/code&gt; contains the path suffixed to a PHP script, if I would call the URL:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://domain.ext/path/to/script.php/foo/bar.htm?a=b&amp;amp;c=d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then &lt;code&gt;$_SERVER['PATH_INFO']&lt;/code&gt; would contain:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/foo/bar.htm&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Traditionaly the &lt;code&gt;$_GET&lt;/code&gt; variables are used for certain parameters like a page to display:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http://domain.ext/page.php?page=about.htm&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This method is easy to program, but not only looks strange, but also is very search engine unfriendly. Most searchengines ignore the QueryString (the part of the URL after the &lt;code&gt;?&lt;/code&gt;). And therefor would index the first &lt;code&gt;page.php?page=x&lt;/code&gt; they would find and ignore the rest.&lt;br&gt;
Some searchengines like &lt;a href="http://www.google.com"&gt;Google&lt;/a&gt; do not ignore the query string, but would give a page without using a querystring for different content a way higher ranking.&lt;/p&gt;
&lt;p&gt;Parsing the &lt;code&gt;$_SERVER['PATH_INFO']&lt;/code&gt; is relatively easy, this code would do most of the stuff just fine:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if (!isset($_SERVER[&amp;#39;PATH_INFO&amp;#39;])){
	$pathbits= array(&amp;#39;&amp;#39;);
}else{
	$pathbits = explode(&amp;#34;/&amp;#34;, $_SERVER[&amp;#39;PATH_INFO&amp;#39;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;$pathbits&lt;/code&gt; array would always contain &lt;code&gt;/&lt;/code&gt; as first element if a path info was provided, otherwise it will be an empty array.&lt;/p&gt;
&lt;p&gt;Here is a quite simple example which parses the path info to decide which file to include:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;?php
if (!isset($_SERVER[&amp;#39;PATH_INFO&amp;#39;])){
	$pathbits= array(&amp;#39;&amp;#39;);
}else{
	$pathbits = explode(&amp;#34;/&amp;#34;, $_SERVER[&amp;#39;PATH_INFO&amp;#39;]);
}
if (!isset($pathbits[1]) || $pathbits[1] == &amp;#34;&amp;#34;){
	$page = &amp;#34;default&amp;#34;
}else{
	$page = basename($pathbits[1]);
}
$file = &amp;#34;./pages/{$page}.php&amp;#34;;
if (!is_file($file)){
	echo &amp;#34;File not found&amp;#34;;
}else{
	require $file;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;</description></item><item><title>Modular Server</title><link>https://blog.affien.com/archives/2004/12/11/modular-server/</link><pubDate>Sat, 11 Dec 2004 19:01:24 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/11/modular-server/</guid><description>&lt;p&gt;(&lt;a href="http://www.w3.org/TR/chips/#uri"&gt;Understanding URIs&lt;/a&gt;)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“A common mistake, responsible for many HTTP implementations problems, is to think this is equivalent to a filename within a computer system. This is wrong. URIs have, conceptually, nothing to do with a file system. One should remember that at all times when dealing with the World Wide Web.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So why do most HTTP servers still heavily rely on the filesystem dictating URL’s?&lt;/p&gt;
&lt;p&gt;This not only tends to create &lt;a href="http://www.w3.org/Provider/Style/URI.html"&gt;&lt;em&gt;Uncool&lt;/em&gt; URI’s&lt;/a&gt;, but also makes it seem logical for filebased dynamic content (more on that &lt;a href="http://blog.w-nz.com/archives/2004/12/11/why-server-side-scripts-arent-that-scalable-at-all/"&gt;in my previous post&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;A http server, actually every server should be nothing more then a wrapper for modules which handle requests of clients.&lt;/p&gt;
&lt;p&gt;The server would only limit itself to a very selected amount of functions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Handling connections&lt;/li&gt;
&lt;li&gt;Exposing an API for the protocol which the modules can us&lt;/li&gt;
&lt;li&gt;Hosting modules&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On startup the server loads modules and binds them to certain URL. Modules remain persistant in the memory and are just signalled a request is made passing the module an API to handle the request.&lt;/p&gt;
&lt;p&gt;I’ll be busy exploring the posibilities to implement this.. there will be more about this.&lt;/p&gt;</description></item><item><title>Why server side scripts aren’t that scalable at all</title><link>https://blog.affien.com/archives/2004/12/11/why-server-side-scripts-arent-that-scalable-at-all/</link><pubDate>Sat, 11 Dec 2004 14:58:27 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/11/why-server-side-scripts-arent-that-scalable-at-all/</guid><description>&lt;p&gt;There are a lot of different types of server scripts, a few examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.php.net/"&gt;&lt;abbr title="Php Hypertext Processor"&gt;php&lt;/abbr&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.perl.com/"&gt;perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.asp.net/"&gt;&lt;abbr title="Active Server Pages"&gt;asp&lt;/abbr&gt;.net (aspx)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://java.sun.com/products/jsp/"&gt;&lt;abbr title="Java Server Pages"&gt;jsp&lt;/abbr&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Practicly all of these were to be used via &lt;a href="http://www.w3.org/CGI/"&gt;&lt;abbr title="Common Gateway Interface"&gt;CGI&lt;/abbr&gt;&lt;/a&gt;, but most of them created tighter intergrations for popular webservers like for the &lt;a href="http://httpd.apache.org/"&gt;Apache Http Server&lt;/a&gt;. Usualy the tight implementations for apache are in the form of modules like &lt;a href="http://www.modpython.org/"&gt;mod_python&lt;/a&gt; to use the general purpose &lt;a href="http://www.python.org/"&gt;python&lt;/a&gt; scripting language as a server side scripts.&lt;/p&gt;
&lt;p&gt;When you, as client, request a page powered by a server side script via CGI (like for instance this blog at the time of writing), the webserver starts the responsible interpreter providing it with some arguments like the POST, GET variables, which then are processed by the PHP interpreter executing the php script, which provides a stream to return to the client.&lt;/p&gt;
&lt;p&gt;This works pretty well with little, not too demanding, scripts.&lt;br&gt;
However, problems arise when a lot of people use the scripts or when the script itself is quite demanding.&lt;/p&gt;
&lt;p&gt;An example could be this blog, this blog uses a &lt;a href="http://www.mysql.com/"&gt;mySQL&lt;/a&gt; database to store its posts and comments. Every time the index page is requested it makes a new connection to the mySQL database server and send a query for the categories, links, latest posts, latest comments, etc. Creating a mySQL connection takes time, sending queries takes time, processing queries takes time for the mySQL server, retreiving the results takes time, processing the results take time, this all just to produce the same content for the index page over and over again, for there are at least 100 times more visits than updates to this blog.&lt;/p&gt;
&lt;p&gt;Some blogs &lt;em&gt;build&lt;/em&gt; there content. When you are viewing posts on these webblogs these posts are not generated for your request but are cached (usualy as normal .html files on the webserver). The control panel to post new blog items is however written in a server side script, and utilizes some sort of database. When you are finished creating new posts the php script will &lt;em&gt;rebuild&lt;/em&gt; the cached pages from the database which will significantly reduce the server stress.&lt;/p&gt;
&lt;p&gt;The downside of these types of blogs is that they contain only a very limited amount of dynamic features, for that would require scripts. Another downside of these blogs is that it is very hard to get such a blog hosted by multiple servers at the same time which usualy happens when a site is very popular and one server can not handle the demand. This is possible for the database powered blog for it stores its data on one centralized datbase server. However, a database powered blog will most likely require more than one server quite soon for it is a far greater strain on the server then a caching weblog. However, it is possible to be done by setting up the blog in such a manner that it stores its cached files on a centralized server too (by normal filesharing). However, I would be suprised when a server using cached pages will ever reach the limit of its server capacities.&lt;/p&gt;
&lt;p&gt;The problem gets bigger when you are dealing with more dynamic server side software like forums. A forum requires some queries. Like a query which retreives the posts, it has no use to cache them for visitors of forums tend to post (yeah.. I know, it’s strange), which would require caches to be updated (which would be an even bigger strain then just using the database anyway).&lt;/p&gt;
&lt;p&gt;A forum however still has got a lot of stuff that is quite static and would run a lot faster if it could be cached. This would be stuff like the templates, the categories architecture, the help pages, the statistics like user count, and the sessions, which are very dynamic but are queried by every page view. These things usualy are requested in every time you download a page.&lt;/p&gt;
&lt;p&gt;Some forums use a cache which consists out of a table in the database which contains all cached stuff serialized so it can be immediately used. But this still means about 10 Kb transfered from the database&lt;strong&gt;every&lt;/strong&gt; time someone views your page!&lt;/p&gt;
&lt;p&gt;This problem even grows bigger when you are developing even more demanding server side projects like a browser based online game.&lt;/p&gt;
&lt;p&gt;I started developing an online game as just a hobby project in PHP, but I soon switched to making my own webserver in C# which caches all the stuff in the memory of the webserver which makes the rewritten stuff &lt;strong&gt;3 times&lt;/strong&gt; faster.&lt;/p&gt;
&lt;p&gt;I figured it would be great if http servers and server side would be less aimed to just handling one request but create more support for inter-request caching. There is limited support for caching in JSP and ASP.net but this is used quite rarely for JSP and ASP.net still focus on just requesting. A server side script should not be loaded on request but rather be loaded already in the form of being able to cache objects like a provider of mySQL connections, which just recycles a connection; a function class which contains all the common used functions already loaded; and off course stuff like templates, sessions, and other cachable things.&lt;/p&gt;
&lt;p&gt;The problem about caching in the memory is that memory can’t be shared between multiple servers, so it isn’t realy scalable. When you would multiple servers and store sessions in the memory it is quite possible that members would just get a “session not found” error when clicking a page which is served by the other server. A possible solution to this problem could be to redirect people when they access “domain.ext”, to a mirror (“s12.domain.ext”). This would avoid session loss. When adding a ‘cacheversion’ value in a table on the shared database server which is changed everytime something is changed for which a cache is created. Requesting just this very small number would be enough to check whether the cache should be rebuild for another server has changed something.&lt;/p&gt;
&lt;p&gt;Just a thought…&lt;/p&gt;</description></item><item><title>My blog</title><link>https://blog.affien.com/archives/2004/12/11/my-blog/</link><pubDate>Sat, 11 Dec 2004 13:28:22 +0100</pubDate><guid>https://blog.affien.com/archives/2004/12/11/my-blog/</guid><description>&lt;p&gt;This is my blog, don’t expect a lot of posts, for I just aren’t good in writing text. (had to correct this post twice :-))&lt;br&gt;
I’ll just post some thoughts, I hope others will find them interesting.&lt;/p&gt;</description></item></channel></rss>