Code:
//
// Algoritmo códigos de liberación DCT3
// Algorithm unlock codes DCT3
//
// indear
//
#include <stdio.h>
#include <string.h>
void ASCII2HEX (unsigned char *origen, unsigned char *destino, int caracteres);
unsigned char convertir_byte_a_hex (unsigned char byte);
unsigned char calculo4_a (char caracter);
void calculo4 (unsigned char *cadena);
void calculo3 (unsigned char *cadena);
void calculo2_a (unsigned char *cadena, unsigned char byte, unsigned char byte2);
void calculo2 (unsigned char *cadena, unsigned char byte, unsigned char byte2);
void calculo1 (unsigned char byte, unsigned char *network_code_h, unsigned char *imei_h);
void calculo1_a (unsigned char *cadena);
void calcular_dct3 (unsigned char *imei, unsigned char *network_code, unsigned char *destino);
void ASCII2HEX (unsigned char *origen, unsigned char *destino, int caracteres)
{
int i, j;
unsigned char aux1, aux2;
j=0;
for(i=0; i<caracteres; i+=2)
{
aux1 = convertir_byte_a_hex(origen[i])<<4;
if (i+1 < caracteres)
aux2 = convertir_byte_a_hex(origen[i+1]);
else
aux2 = 0;
destino[j] = aux1 | aux2;
j++;
}
}
unsigned char convertir_byte_a_hex (unsigned char byte)
{
if ((byte > 57) || (byte < 48)) // '0' a '9'
return (byte-55);
else
return (byte-48); // 'A' a 'F' o otro caracter
}
unsigned char calculo4_a (char caracter)
{
unsigned char aux1, aux2, aux3, temp;
int i;
aux1=0;
aux2=7;
temp=0;
for (i=0; i<8; i++)
{
aux3=caracter;
aux3=aux3>>aux2;
aux3&=1;
aux3=aux3<<aux1;
temp|=aux3;
aux1++;
aux2--;
}
return temp;
}
void calculo4 (unsigned char *cadena)
{
char temp[12];
int i;
memcpy(temp, cadena, 12);
for (i=0; i<12; i++)
{
cadena[11-i]=calculo4_a(temp[i]);
}
}
void permu1(unsigned char *network_code_hex, unsigned char *tabla, unsigned char *imei_hex)
{
unsigned char *puntero;
int i;
puntero=tabla;
for (i=0; i<11; i++) {
calculo1(*puntero, network_code_hex, imei_hex);
calculo2(network_code_hex, 0, 8);
calculo3(network_code_hex);
calculo2(network_code_hex, 8, 0);
puntero++;
}
calculo1(tabla[11], network_code_hex, imei_hex);
calculo4(network_code_hex);
}
void calculo3 (unsigned char *cadena)
{
unsigned char aux1, aux2, aux3, temp1, temp2;
char temp[12];
int i;
memcpy(temp, cadena, 12);
temp2=12;
temp1=7;
aux1=3;
for(i=0; i<12; i++)
{
aux2=temp1;
aux3=aux1;
aux2=temp[aux2];
aux2^=0xFF;
aux2|=temp[aux3];
temp2--;
if (temp1==0)
temp1=12;
temp1--;
if (aux1==0)
aux1+=12;
aux3=temp2;
cadena[aux3]^=aux2;
aux1--;
}
}
void calculo2_a (unsigned char *cadena, unsigned char byte, unsigned char byte2)
{
unsigned char aux1, aux2, aux3;
unsigned char *puntero;
int i,j;
if (byte==0)
return;
for (i=0; i<byte; i++)
{
aux1=cadena[byte2+3];
aux1&=1;
puntero=cadena+byte2;
for (j=0; j<4; j++)
{
aux2=*puntero;
aux3=aux2;
aux2=aux2>>1;
aux1=aux1<<7;
aux2|=aux1;
aux3&=1;
*puntero=aux2;
aux1=aux3;
puntero++;
}
}
}
void calculo2 (unsigned char *cadena, unsigned char byte, unsigned char byte2)
{
calculo2_a(cadena, 10, byte);
calculo2_a(cadena, 31, byte2);
}
void calculo1 (unsigned char byte, unsigned char *network_code_h, unsigned char *imei_h)
{
unsigned char aux1, aux2;
int contador;
unsigned char *puntero, *puntero2;
puntero=network_code_h;
puntero2=imei_h;
contador=0;
aux1=0;
while (contador < 12)
{
aux2=aux1;
aux2=(aux2>>1) % 3;
aux2&=1;
aux2*=byte;
aux2^=(*puntero2);
(*puntero)^=aux2;
aux1++;
puntero++;
puntero2++;
contador++;
}
calculo1_a(network_code_h);
}
void calculo1_a (unsigned char *cadena)
{
// 60 bytes
char tabla1[] = {0x01,0x09,0x04,0x08,0x0B,0x05,0x09,0x08,0x06,0x0A, \
0x01,0x03,0x0B,0x06,0x0A,0x00,0x08,0x07,0x0B,0x0A, \
0x01,0x05,0x00,0x08,0x03,0x01,0x09,0x00,0x02,0x0A, \
0x05,0x03,0x07,0x02,0x0A,0x00,0x04,0x03,0x0B,0x02, \
0x05,0x09,0x00,0x04,0x07,0x01,0x05,0x04,0x02,0x06, \
0x09,0x07,0x0B,0x02,0x06,0x04,0x08,0x03,0x07,0x06};
// 60 bytes
char tabla2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, \
0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x00,0x01,0x01, \
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x01, \
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
unsigned char *puntero=cadena;
unsigned char aux1, aux2;
int contador1, contador2, contador3;
char variable_8c[12];
contador1=0;
aux1=0;
aux2=0;
while (contador1<12) {
contador2=5;
aux2^=*puntero;
while (contador2>0) {
if ((tabla2[aux1] == 0) && (contador1 <6)) {
variable_8c[tabla1[aux1]]=*puntero;
}
else {
variable_8c[tabla1[aux1]]^=*puntero;
}
aux1++;
contador2--;
}
contador1++;
puntero++;
}
for (contador3=0; contador3<12; contador3++)
variable_8c[contador3]^=aux2;
memcpy(cadena, variable_8c, 12);
}
void calcular_dct3 (unsigned char *imei, unsigned char *network_code, unsigned char *destino)
{
char tabla[] = {0xb1,0x73,0xe6,0x5a,0xab,0x47,0x8e,0x0d,0x1a,0x34,0x68,0x0b}; //12 bytes
char network_code_h[12], imei_h[12];
int i, j;
unsigned char aux1;
memset(network_code_h, 0, sizeof(network_code_h));
memset(imei_h, 0, sizeof(imei_h));
ASCII2HEX(network_code, network_code_h, (int)strlen(network_code));
ASCII2HEX(imei, imei_h+2, 14);
for (i=2; i<12; i++)
imei_h[i]^=0xa5;
permu1(network_code_h, tabla, imei_h);
j=0;
for (i=0; i<5; i++)
{
aux1=network_code_h[i];
if ((aux1&0x80) == 0x80)
aux1+=0xa0;
if ((aux1&0x08) == 0x08)
aux1+=0xfa;
destino[j]=(aux1 >> 4) + 0x30;
j++;
destino[j]=(aux1 & 0x0F) + 0x30;
j++;
}
destino[j]=0;
}
void main()
{
// examples - ejemplos
char destino[11];
calcular_dct3( "111111111111119", "22222", destino); // Code1 use network code
printf("#pw+%s+1#\n", destino); // Codigo1 usar el codigo de operador
calcular_dct3 ( "111111111111119", "FFFF", destino); // Code2 use GID1
printf("#pw+%s+2#\n", destino); // Codigo2 usar el GID1
calcular_dct3 ( "111111111111119", "1234", destino); // Code3 use GID2
printf("#pw+%s+3#\n", destino); // Codigo3 usar el GID2
calcular_dct3 ( "111111111111119", "222221234567890", destino); // Code4 concatenate MCC+MNC+MSIN (15 digits)
printf("#pw+%s+4#\n", destino); // Codigo4 concatenar MCC+MNC+MSIN (15 dígitos)
}
cheers