#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""(Un)Roast a password sent via AIM/ICQ.
The OSCAR protocol (used by AIM and ICQ) uses two alternative methods to pass
authentification credentials. While the second uses an MD5 hash, the first
only XORs the password with a static character set.
This is meant to recover a forgotten password that is still stored by an ICQ
client.
Anyway, use Jabber/XMPP.
:Copyright: 2006 Jochen Kupperschmidt
:Date: 22-Mar-2006
:License: MIT
"""
from itertools import cycle
CHARS = '\xF3\x26\x81\xC4\x39\x86\xDB\x92\x71\xA3\xB9\xE6\x53\x7A\x95\x7C'
def roast(password):
"""(Un)Roast a password.
Its characters are `XOR`ed with those in the roast array.
When this function is applied on the output of itself, the result equals
the original input string.
"""
chars = cycle(CHARS)
return ''.join(chr(ord(char) ^ ord(chars.next())) for char in password)
if __name__ == '__main__':
# tests
TEST_STRING = '12345secret'
TEST_ROASTED = '\xc2\x14\xb2\xf0\x0c\xf5\xbe\xf1\x03\xc6\xcd'
assert roast(TEST_STRING) == TEST_ROASTED
assert roast(roast(TEST_STRING)) == TEST_STRING
# example usage
print roast('\xba\x65\xd0\xb7\x4c\xe5\xb0\xe1\x50')