// tobias@ccc.de Source Code von andreas@ccc.de 
// Nokia Security Code Generator Source Code 

/*
 * security_code.c
 */

unsigned char data_1[] =
{ 0x17,0x2D,0x25,0x29,0x17,0x2D,0x11,0x20,0x12,0x27,0x0E,0x23,0x1B,0x0B,0x27 };
unsigned char data_2[] = { 2,6,9,4,9 };
unsigned char data_3[5][15] = {
{ 0x17,0x2C,0x43,0x0E,0x22,0x13,0x43,0x4D,0x59,0x16,0x22,0x4E,0x37,0x58,0x5C },
{ 0x4B,0x2D,0x5A,0x12,0x24,0x43,0x35,0x4A,0x47,0x36,0x13,0x17,0x53,0x24,0x13 },
{ 0x22,0x47,0x1D,0x4E,0x62,0x22,0x41,0x17,0x26,0x30,0x2C,0x57,0x38,0x36,0x12 },
{ 0x42,0x2E,0x18,0x2D,0x4E,0x20,0x0E,0x23,0x4A,0x60,0x47,0x25,0x30,0x39,0x3F },
{ 0x21,0x24,0x19,0x13,0x1A,0x25,0x1F,0x36,0x4F,0x20,0x2E,0x43,0x36,0x21,0x15 }
};
unsigned char data_4[] = { 1, 5, 7, 6, 3 };

int security_code(char* imei, char* sec_code) {
  int i,j;
  unsigned char k;
  char local_1[15];

  if(strlen(imei) != 15)
    return 0;
  for(i = 0; i < 15; i++) {
      local_1[i] = imei[i] - data_1[i];
  }
  for(i = 0; i < 5; i++) {
    k = 0;
    for(j = 0; j < 15; j++) {
      k += (local_1[j] ^ local_1[(j + data_2[i]) % 15]) * data_3[i][j];
    }
    k = (k + data_4[i]) % 10;
    sec_code[i] = k + 0x30;
  }
  return 1;
}

main(int argc, char** argv) {
  char sec_code[6];

  security_code(argv[1], sec_code);
  sec_code[5] = 0;
  printf("%s\n", sec_code);
}


