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 */