Psi statistics generator and password decoding

I use Psi as my main chat client, at home and at work. It does most things I want it to do and works quite well. Not to forget the awesome XMPP service and forms support.

On my quest to find/hack a tool to merge histories of several Psi instances, I came across the Psi tools wiki page, listing Psist.


Psist is the Psi statistics generator and utilizes your chat history to generate a nice HTML page, showing the people you chat with most, the times you chat most, the times you chat with certain people and the message-to/from rate of remote users.

Unfortunately, that tool does not work anymore. That's nothing to wonder about, given that the latest release is from 2006. But since it's a simple Perl script, I took some time to fix it and make it compatible with the most recent (0.14) version of Psi. The code is available on my Git server.

Psi password encryption

While sifting the Psi source code and configuration files, I came across the password entries in account.xml and the related encodePassword() and decodePassword() functions in src/common.cpp.

As a small exercise, I re-implemented the password encryption and decryption algorithm in PHP:

 strlen($enc)) {
        $pass .= chr(
            base_convert(substr($enc, $n1, 4), 16, 10) ^ ord($key[$n2++])
        if ($n2 >= strlen($key)) {
            $n2 = 0;

    return $pass;

 * Encodes a string with a key.
 * Algorithm:
 * Each character of the string is XORed with the respective character
 * of the key, printed as 4-digit hexadecimal number and appended
 * to the encrypted string.
 * @param string $str String to encrypt
 * @param string $key Key used to encrypt the string
 * @return string Encrypted string
function encode($str, $key)
    $enc = '';
    for ($n1 = $n2 = 0; $n1 < strlen($str); $n1++) {
        $enc .= sprintf('%04x', ord($str[$n1]) ^ ord($key[$n2++]));
        if ($n2 >= strlen($key)) {
            $n2 = 0;
    return $enc;

Written by Christian Weiske.

Comments? Please send an e-mail.