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​

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)) {
            break;
        }
        $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.