Listing 1: Functions used to create activation and serialization codes


typedef unsigned long ulong;

// both keys must be odd
#define SCODE_KEY 219048765 // for serialization codes
#define ACODE_KEY 740030213 // for activation codes

typedef char code[ 15 ];

struct regdata {
    char username[ 7 ];  // 7x 'A'-'Z','0'-'9' or ' '
    int module;          // 0-99
    int months;          // 0-599
    int salt;            // 0-3171
};

struct radixdat {
    ulong i, j;
};

extern void regdata2code( const struct regdata *r,
                          code *c, ulong key )
{
    struct radixdat d = { 0, 0 };

    int i;
    for ( i = 0; i < 7; ++i ) {
        int n;
        if ( isupper( r->username[ i ] ))
            n = r->username[ i ] - 'A';
        else if ( isdigit( r->username[ i ] ))
            n = r->username[ i ] - '0' + 26;
        else
            n = 36;

        if ( i < 5 )
            d.i = d.i * 37 + n;
        else
            d.j = d.j * 37 + n;
    }

    d.j = d.j * 100 + r->module;
    d.j = d.j * 600 + r->months;

    d.i = d.i * 61 + ( r->salt / 52 );
    d.j = d.j * 52 + ( r->salt % 52 );

    d.i = encrypt( d.i, key );
    d.j = encrypt( d.j, key );

    int2alnum( d.i, (char *) c );
    int2alnum( d.j, (char *) c + 7 );
    ( (char *) c )[ 14 ] = '\0';
}

extern void code2regdata( const code *c,
                          struct regdata *r, ulong key )
{
    struct radixdat d = {
        decrypt( alnum2int( (char *) c ), key ),
        decrypt( alnum2int( (char *) c + 7 ), key )
    };

    int i;

    r->salt = ( d.i % 61 ) * 52 + d.j % 52;
    d.i /= 61;
    d.j /= 52;

    r->months = d.j % 600, d.j /= 600;
    r->module = d.j % 100, d.j /= 100;

    for ( i = 6; i >= 0; --i ) {
        int n = ( i < 5 ? d.i : d.j ) % 37;
        if ( n < 26 )
            r->username[ i ] = 'A' + n;
        else if ( n < 36 )
            r->username[ i ] = '0' + ( n - 26 );
        else
            r->username[ i ] = ' ';
        *( i < 5 ? &d.i : &d.j ) /= 37;
    }
}

static void int2alnum( ulong n, char *p )
{
    int i;
    for ( i = 6; i >= 0; --i ) {
        int v = n % 36;
        if ( v < 26 )
            p[ i ] = 'A' + v;
        else
            p[ i ] = '0' + ( v - 26 );
        n /= 36;
    }
}

static ulong alnum2int( const char *p )
{
    ulong n = 0;
    int i;
    for ( i = 0; i < 7; ++i )
        if ( isalpha( p[ i ] ))
            n = n * 36 + p[ i ] - 'A';
        else
            n = n * 36 + p[ i ] - '0' + 26;

    return n;
}

/* End of File */