Autor Tema: comparar dos array  (Leído 2429 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
comparar dos array
« en: 24 de Marzo de 2016, 17:31:10 »
Hola, tengo el siguiente problema:
Estoy usando el proyecto de Suky, SD FAT. La idea es leer una clave que esta en un txt y compararla con la que se le ingresa al pic.
el archivo txt tiene mas de 600 lineas de  claves.
entonces tengo dos array  y quiero comparar si son iguales:

Código: C
  1. char key[7] = {'*','1','2','3','4','5','6'};   // Clave de ejemplo
  2. Char mem[7];                                                       // Array temporal


Código: C
  1. for(k=0;k<=512;k++)   {         // Recorre todas las lineas del archivo
  2.     //    printf("%c",BufferFAT[k]);            // imprime carácter
  3.        
  4.         mem[a]=BufferFAT[k]; a++;           // va guardando  los dígitos
  5.        
  6.        if (a==6){                                                         // va analizando de 7 en 7  o deberia ser hasta que encuentre un "/n"
  7.          if( !memcmp( mem, key, sizeof( mem ))) {    // Comparación
  8.             printf( "cadenas iguales\n" ); }
  9.             else {
  10.             printf( "cadenas distintas\n" );}
  11.      a=0;
  12.      }

La ideas es leer el archivo, y  buscar la cadena. La comparación funciona, pero lo que no logro es leer de 7 en 7 .

Si alguien le interesa, aquí esta el proyecto completo, con simulación y todo:
https://www.dropbox.com/s/qafj0r34x745ncf/8_SD_Suky_ver18.rar?dl=0
http://www.winimage.com/download.htm  para editar la imagen

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #1 en: 24 de Marzo de 2016, 18:25:14 »
Citar
La ideas es leer el archivo, y  buscar la cadena. La comparación funciona, pero lo que no logro es leer de 7 en 7 .

Hay una cosa que no entiendo, y es por que quisieras comparar de 7 en 7.

Código: C
  1. for(k=0;k<512;k++)   {         // Recorre todas las lineas del archivo
  2.     //    printf("%c",BufferFAT[k]);            // imprime carácter
  3.  
  4.        
  5.         if(memcmp(&BufferFAT[k],key,7) == 0 )       // Analiza los 7 caracteres a apartir de BufferFAT[k]
  6.         {
  7.                 return 1;                                             // Caso de ser 0 significa coincidencia y salimos para decir que lo encontramos
  8.         }
  9.  
  10.         if (k== (512-7-1))
  11.         {
  12.                 return 0;       //No se encontro nada.  Caso que se supero lo leido, es decir si llega a 504, el proximo es 505 y solo van a restar 6 caracteres (a 511)
  13.                                 //lo cual es imposible que existan 7, este resto debera tenerse en cuenta si es que hay varios buffers en la lectura
  14.         }
  15. }

La diferencia entre el codigo que pase y el tuyo es que mi codigo si tenes algo asi en el archivo:

Citar
QQWE*123456DSAWE

Lo deberia reconocer, En tu codigo hay algunas cosas que me causan dudas.. Por ejemplo:

Código: C
  1. for(k=0;k<=512;k++)

Normalmente uno usa un buffer de potencia a la 2 y creo que por eso elegiste 512, pero ahi pasa por 513 valores, deberia ser k<512, es decir de 0 a 511
La otra es que SI o SI tus constraseñas deben tener si o si 7 caracteres y no tener ninguna separacion, si hay un salto de linea entre medio estas complicado ya que solo coincidira completo la lectura del pass luego de 7 saltos de lineas ( ya que los intermedios tendrian el salto de linea incluido ). Y si llegas a querer poner un pass mas largo o queres cambiar el tamaño de los pass debido a que no estan separados te vas a complicar.

Igual mi codigo puede tener problemas, requiere que los pass esten separados por un caracter que NO puede pertenecer al set que se usa en los password suponete un salto de linea.

Citar
PASS1ACA
PASS2ACA
PASS3ACA

Todavia no hablamos como es que estan almacenados los pass en tu archivo de texto, por lo cual el codigo puede variar y que me este equivocando.
Si tomo que el * es el primer caracter del pass en el texto y lo tenes asi para indicar cuando comienza, entonces lo primero que haria es preguntar por eso, y si no se cumple continuar, si coincide recien ahi comparar, en ese caso no necesitaria una key de 7 sino de 6.

Código: C
  1. for(k=0;k<512;k++)   {         // Recorre todas las lineas del archivo
  2.  
  3.         if(BufferFAT[k] == '*') continue;
  4.        
  5.         if(memcmp(&BufferFAT[k+1],key,6) == 0 )       // Analiza los 7 caracteres a apartir de BufferFAT[k]
  6.         {
  7.                 return 1;                                             // Caso de ser 0 significa coincidencia y salimos para decir que lo encontramos
  8.         }
  9.  
  10.         if (k== (512-7-1))
  11.         {
  12.                 return 0;       //No se encontro nada.  Caso que se supero lo leido, es decir si llega a 504, el proximo es 505 y solo van a restar 6 caracteres (a 511)
  13.                                 //lo cual es imposible que existan 7, este resto debera tenerse en cuenta si es que hay varios buffers en la lectura
  14.         }
  15. }
« Última modificación: 24 de Marzo de 2016, 18:32:51 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #2 en: 24 de Marzo de 2016, 18:38:15 »
Citar
La ideas es leer el archivo, y  buscar la cadena. La comparación funciona, pero lo que no logro es leer de 7 en 7 .

Hay una cosa que no entiendo, y es por que quisieras comparar de 7 en 7.
....

Este código lo encontré, solo modifique la imagen para crear una lista así:
*123456789012345
-123456789012345
<123456789012345

digo que de 7 en 7 por poner un ejemplo, porque este código va imprimiendo todo los caracteres del txt,entonces quiero es ir recorriendo e  ir guardando 7 caracteres  para compararlos con la clave.
por ejemplo, suponiendo que la clave es de  7 caracteres  "1234567"

en el txt esta:
1r45689           << guarda estos 7 en una array y compara con la clave, si no es, continua con el siguiente.
12t4575
12345r6
1234567           << esta es  la correcta


En realidad no es claves, la idea es buscar cualquier palabra en un archivo de texto.

Como siempre gracias por comentar! :)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #3 en: 24 de Marzo de 2016, 19:00:58 »
Claro pero esto:

Código: [Seleccionar]
1r45689
12t4575
12345r6
1234567
equivale a esto

Código: [Seleccionar]
1r45689\n12t4575\n12345r6\n1234567
Suponiendo que solo se agregue un \n y no un \r\n al final, dependiendo del sistema operativo, si eso ocurre y tomas de a 7 en 7 como vos decis

1era: 1r45689
2da: \n12t457
3ra: 5\n12345

Asi hasta que en la 8va/9na tengas nuevamente algo sin el \n

Por eso mismo te estaba preguntando cual es la cadena exacta que tenes en el archivo de texto. Si es algo asi:

Código: [Seleccionar]
*123456789012345
-123456789012345
<123456789012345

O buscaria uno por 1, o utilizaria el \n o \r para comenzar a buscar la nueva linea. En resumen tenes que parsear esa cadena de texto. Espero haberme hecho entender cual era mi objetivo antes. Si me decis exactamente como esta conformado el archivo de texto ( con \n o \r\n ) de seguro podemos llegar a una solucion
« Última modificación: 24 de Marzo de 2016, 19:03:58 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #4 en: 24 de Marzo de 2016, 19:18:10 »
Claro pero esto:
...

Ok, asumiendo que el txt sea exactamente esas 4 lineas:
1234560
r456637
1234567      <<clave correcta
g123455

¿Cómo debe ser el recorrido para encontrar la tercera linea que es la correcta?

puse a=0, para que el array temporal iniciara a llenarse otra vez desde la posición 0 con el valor de "k", para seguir haciendo la comparacion. pero, no funciona

por ejemplo si lo hago así, si funciona, obviamente si la clave esta en la linea uno, de ahí la idea de ir llenando un array con los valores de la linea.

Código: [Seleccionar]
  if( FAT_OpenFileAndRead(NombreCorto,DirectorioRaiz, 'o', BufferFAT)!=FAT_ERROR  )    {
     for(k=0;k<=512;k++)   {
        printf("%c",BufferFAT[k]);
         
        mem[k]=BufferFAT[k]; // guardo los digitos
         if (k==6){
         if( !memcmp( mem, key, sizeof( mem ))) {
            printf( "cadenas iguales\n" ); }
            else {
            printf( "cadenas distintas\n" );}
     }





Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #5 en: 24 de Marzo de 2016, 20:07:01 »
Quedan 2 opciones.

O usas el primer codigo que pase. Que no le importaria para nada lo que tengas en el medio, es decir:

Código: C
  1. for( k = 0 ; k < (sizeof(BufferFAT) - sizeof(key)) ; k++ )
  2. {
  3.         if(memcmp(&BufferFAT[k], key , sizeof(key)) == 0 )
  4.         {
  5.                 return 1;
  6.         }
  7. }

La unica condicion de este codigo es que lo que "separa" los pass no este incluido en el pass. Es decir si usas la coma ',' para separar los pass, tus pass no podrian tener comas. Por que implicaria una posibilidad de que se pueda encontrar un pass juntando 2.

-------------------------------------------------------------------------------------------------------------------------------------

O si aun asi queres dividirlo en 7 en 7 ( o en 8 o 9 segun los demas caracteres) como vos queres. Entonces uso la primer linea para saber cuando es que comienza la segunda, y con eso saber cada cuanto tengo que saltar. La explicacion en los comentarios, Observa que el primer for, solo deberia actuar 8/9 veces, el otro for se reduce en cantidad a round(512 / (8 o 9)) vueltas. Pero lo veo como una solucion poco simple y propensa a fallas. Y prefiero la anterior, Este codigo puede tener muchas fallas, si un pass es un poco mas largo o corto fallaria, si no se usa salto de lineas y se usan comas para separar los pass este codigo tambien fallaria.

Código: C
  1. // Este for se deberia ejecutar 1 sola ves en toda la lectura del archivo
  2.  
  3. for( sizelinea = 0 ; sizelinea <= 20 ; ++sizelinea )
  4. {
  5.         if((BufferFAT[sizelinea] == '\n') || (BufferFAT[sizelinea] == '\r'))            //Compruebo sea cual sea \n o \r
  6.         {
  7.                 if((BufferFAT[sizelinea+1] != '\n') && (BufferFAT[sizelinea+1] != '\r') // Compruebo que la proxima letra no sea la anteiro
  8.                         sizelinea++;
  9.                         break;
  10.         }
  11.         if(sizelinea == 20 ) { sizelinea = 0; }                                         //Proteccion de que no exista mas nada
  12. }
  13.  
  14. /*
  15.  Hasta aqui tengo la cantidad de letras que hay en el primer pass, es decir con el \n y/o \r incluido
  16.  Hay que asegurarme que todos los demas pass sean de igual tamaño, si no son iguales significaria un error grave.
  17.  Supongamos esto:
  18.  
  19. 1234560
  20. g123455
  21. 1234567
  22.  
  23.  El primer for utiliza la primer linea buscando un \n o un \r , lo cual si o si deberia haber un salto de linea
  24.  Si existe una \n sola el valor de sizelinea sera de 8,
  25.  
  26. 1234560\ng123455\n1234567  
  27.        ^
  28.        Indice 7, lo cual el 8 lo pondria en la primer letra del 2do pass
  29.  
  30. 1234560\ng123455\n1234567
  31.                  ^
  32.                  Indice 15 esta el otro \n, por lo cual en 16 esta mi tercer pass, es decir iria de 8 en 8
  33.  
  34. en caso de existir una \n\r o \r\n, el valor sera 9
  35.  
  36. 1234560\n\rg123455\n\r1234567
  37.           ^
  38.           Indice 8 esta el ultimo de los \r o \n , en 9 comienza mi segundo pass.
  39.  
  40. 1234560\n\rg123455\n\r1234567
  41.                     ^
  42.                     Indice 17 el ultimo \r o \n , asi que en 18 comienza mi tercer pass. es decir de 9 en 9.
  43.  
  44. Ahora si los pass mantienen un largo constante y no se modifican para nada,  podria ir saltando de 9 en 9, o de 8 en 8, lo cual estaria saltando ademas los \n o \r\n o \n\r sin importar lo que use. ( Siemrpe y cuando sean salto de lineas, sino tengo que cambiar arriba los delimitadores )
  45.  
  46. La principal limitacion es que SI o SI debe respetarse el formato, es decir todos deben tener \n o \n\r , si algunos tienen \n y otros tienen \n\r es un problema. Al igual que el largo del pass
  47.  
  48. */
  49.  
  50. for( k = 0 ; k < (sizeof(BufferFAT) - sizelinea) ; k += sizelinea)   {         // Recorre todas las lineas del archivo
  51.  
  52.         if(memcmp( &BufferFAT[k], key, sizeof(key)) == 0 )
  53.         {
  54.                 return 1;
  55.         }
  56. }

Es tu decision, uno me parece que es mas rapido, que es el ultimo pero con grandes limitaciones, el primero es mas lento pero con menor limitacion. De ultima, en el ultimo podes directamente no calcular el valor inicial y ponerlo vos, lo cual vas a tener que conocer que cantidad caracteres hay entre medio de los 2 pass.

Código: C
  1. sizelinea = sizeof(key) + 1;
  2. for( k = 0 ; k < (sizeof(BufferFAT) - sizelinea) ; k += sizelinea)   {         // Recorre todas las lineas del archivo
  3.  
  4.         if(memcmp( &BufferFAT[k], key, sizeof(key)) == 0 )
  5.         {
  6.                 return 1;
  7.         }
  8. }

Ademas no tengo en cuenta si es que necesitas mas de 1 buffer para leer todo el archivo. Asi que eso es algo que vas a tener que arreglar.
En lo demas espero que quede mas claro.
« Última modificación: 24 de Marzo de 2016, 20:15:28 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #6 en: 24 de Marzo de 2016, 20:45:10 »
Quedan 2 opciones.
....

Listo, con la opción 1, simulado funciona perfecto. Gracias!

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #7 en: 25 de Marzo de 2016, 02:56:34 »
cuando pensé que lo tenia listo, me surgio un problema  :shock: , en si la  lista de llaves final será de la  siguiente forma:
000000B8C52C
000000B8C52X
000000B8C52F
...
el tamaño nunca va cambiar, pero el archivo txt va tener almenos 500 a 600 llaves o lineas.
la llave se ingresa al pic de esta forma 00-00-00-B8-C5-2C, es decir me entrega 6 hex,pero los datos del archivo txt son string.  :?

Código: C
  1. for(i=0;i<8;++i) buffer[i]=touch_read_byte();             // Llenando buffer con ID   de la llave    
  2.  for(i=6;i!=0;--i) fprintf(uart2,"%2X",buffer[i]);                           // Imprimir buffer en formato HEX
  3.  
  4. //Va completando la llave y luego imprime los 6 hex
  5. 000000B8C52C   // esto es lo que  sale por el serial debug

obviamente no sirve  :( , pero básicamente quiero hacer eso, tal cual como lo hiciste en tu código:

Código: C
  1. for( k=0; k< (sizeof(BufferFAT) - sizeof(buffer)) ; k++ )
  2. {
  3.         if(memcmp(&BufferFAT[k], buffer , sizeof(buffer)) == 0 )
  4.         {
  5.                 fprintf(uart1,"ok"); break;   // return 1;
  6.         }
  7.  
  8.   }

si el buffer estuviera definido de esta forma  char key[7] = {'4','5','6','7','g','6','h'};   // Clave de ejemplo
no abría problemas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #8 en: 25 de Marzo de 2016, 03:15:46 »
Entonces el problema que tenes es que estan almacenadas como string, pero son hex Y luego te gustaria compararlos como hacias antes.

EDIT:

Edito un poco por que estoy en dudas.

- Como podes tener 00 si la entrada va a ser de un teclado ? Es imposible que asi sea.
- Deberias decir que caracteres son validos para el password, es decir Numeros y letras, letras mayusculas y minusculas, ¿signos?. Mientras mas agregues mas dificil puede llegar a ser la reconstruccion o no. Depende del metodo empleado
- 2X no es un numero hexa en tu ejemplo, que letra/numero/simbolo es B8 ?, O son coordenadas de donde se toca el touch ? (imagino que es un touchpad por el nombre).
- Si son coordenadas puede ser un problema, deberias limitar el rango de valores, ya que no podrias distinguir sino el separador de cada pass.

Soluciones que se me ocurren:

1 - Una solucion es que termines comparandolo con algo de 14 y no 7 valores. Esto implica que la contraseña ingresada deba ser desmembrada para que entre en los 14 lugares. Es decir se hace en ese momento nomas ( por el caso de tiempo de CPU ocupado), y ocuparia 14 lugares como maximo en RAM siempre.

2 - Otra solucion es que de esos 7 valores se genere por cada uno el valor correspondiente y luego se compare. Esta solucion puede tener 2 formas.
La primera es crear un array de 14 lugares que sera destruido al salir de esa funcion, transformar la llave a esos 14 lugares, simplificando la entrada del pass y guardado. Tiene un costo computacional inicial igual que el anterior, pero esta ves el maximo RAM consumido aumenta a 21 lugares de RAM, por un momento, ya que luego se destruye y volvemos a tener 7 lugares, es decir deberias tener 14 lugares disponibles en el stack.

La otra es calcularlo a medida que se necesita, esto posee un costo computacional altisimo, pero solo ocuparias como maximo 9 espacios de RAM ( key + 2 lugares en el stack ). y esos 2 desaparecerian al finalizar la funcion.

3 - Otra solucion es que sean los datos del archivo quien se tomen de a par y se comparen con la llave. Esta solucion tiene tambien un gran costo computacional, ya que deberias hacerlo por cada uno de esos 512 valores. Ademas aumenta la complejidad por que antes de obtener esos valores se deberia verificar que se encuentran dentro el set de letras/numeros/etc que pueden ir en el password.

La 1ra y 2da solucion tiene una rapida implementacion, la otra va a ser necesario crear un memcpy propio que efectue el mismo trabajo pero que tenga en cuenta lo demas.

Y si tuviera que elegir por el costo computacional me quedo entre la 1ra y la 2da, todo va a depender si es que necesitas ademas la llave en otro lado, es decir si necesitas muchas veces tener la llave en texto comun "4567g6h", entonces mejor mantenerla asi. Ahora si no te importa como esta almacenada la llave iria por la 1ra y la mantendria como "34353637673668".

-----------------------------

600 llaves * ( 14 caracteres pass  + 2 salto de linea/retorno de carro (peor caso) ) = 9600 bytes

Y estas leyendo cada 512, eso significa que debe repetirse esto 17 a 19 veces. Por cada password.
Vas a tener que pensar como vas a hacer lo siguiente tambien:

Si tenemos 2 caracteres extras por pass, es decir \r\n, da justo que 512/16 = 32 es un entero. Lo cual vas a poder leer uno tras otro en 512 bytes y no modificar los indices de lectura.
Si por casualidad tenemos 1 solo caracter extra es decir \n solo, 512 / 15 = 34.133, o mejor dicho 34 password, y 2 bytes del proximo password que va a venir en los otros 512 bytes del buffer. Los cuales vas a tener que arreglartelas para que funcione correctamente, ya sea guardando ese valor creando una funcion especial de lectura y comenzando desde otro indice luego o modificando el indice de lectura del archivo (o byte offset como lo llama FatFS, que imagino que la libreira que hizo Suky lo posee).
« Última modificación: 25 de Marzo de 2016, 05:18:56 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #9 en: 25 de Marzo de 2016, 13:42:01 »
Entonces el problema que tenes es que estan almacenadas como string, pero son hex Y luego te gustaria compararlos como hacias antes.

EDIT:

....

En realidad es el ID de la llave dallas, cuando el pic lee el touch, siempre arroja en el formato de 6 hex ... como son mas de 500 llaves que debo autenticar para un posterior evento, pensé en una eeprom, pero me gusta mas la idea de poder editar un archivo de texto e ir agregando las llaves que quiera. ¿o será mejor una eeprrom?

Muchas gracias por tu sugerencia, trabajaré en las opciones que me recomiendas. ((:-))

EDIT


Lo estoy haciendo lo mas sencillo posible, suponiendo que solo entre un carácter "0x01" y en la lista este el "1"
Código: C
  1. char key2[3];
  2. for(i=0;i<8;++i) buffer[i]=touch_read_byte();             // Llenando buffer con ID   de la llave    
  3. for(i=0;i<1;++i) key2[i]=buffer[i];                               // Guardar el primer carácter  en el array key2, siempre es 0x01  
  4.  
  5.  
  6.  for( k=0; k< (sizeof(BufferFAT) - sizeof(key2)) ; k++ )
  7. {
  8.         if(memcmp(&BufferFAT[k], buffer , sizeof(key2)) == 0 )
  9.         {
  10.                 fprintf(uart1,"ok"); break;   // return 1;
  11.         }
  12.  
  13.   }
   

Esta claro que el bufferFAT[0]={'1'} y key2[0]={0x01}, es el mismo valor pero uno es string y el otro es hex. No tengo ni idea, de que forma puedo comparar estos valores... tendría que dividir 0x01 en "0,1"? ¿cómo se hace eso?... Seguiré estudiando.
« Última modificación: 25 de Marzo de 2016, 19:18:13 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #10 en: 25 de Marzo de 2016, 23:10:31 »
Pensemos un poco, un Hexadecimal tiene 16 valores, de 0 a 9 y A a F.

Lo cual en el archivo TXT vamos a leer '0' a '9' o 'A' a 'F', esto es un caracter ASCII, usando una tabla ASCII que podes encontrar miles en google. te das cuenta que

Código: [Seleccionar]
'0' es igual a 0x30
........Aca los demas numeros .....
'9' es igual a 0x39

.. Aca otros letras/signos ...

'A' es igual a 0x41
 ... Aca las demas letras que estan entre A y F ....
'F' es igual a 0x46

En resumen vos estarias leyendo ese valor y si observas hay un patron simple, si el Hex es de 0x00 a 0x09 para convertirlo a un caracter ASCII solo le sumas 0x30 , si es de 0x0A a 0x0F le sumas 0x41. Voy a suponer por un instante que es esta llave que esta en el TXT:

"000000B8C52C"

Ahora tenemos nuestra llave ( que voy a copiar una del codigo anterior y modificar para que sea correcto ) en formato hexadecimal recolectado desde el llavero/iButton

char key[6] = {0x00,0x00,0x00,0xB8,0xC5,0x2C};

Como te decia una de las opciones era crear un nuevo array que transforme esos valores y los convierta en strings.

Código: C
  1. char    key_in_char[sizeof(key)*2];
  2.  
  3. for( i=0; i < sizeof(key) ; ++i)
  4. {
  5.         key_in_char[i*2] = key[i]>>4;           // Nibble alto, Del par corresponde a la letra de la izquierda
  6.         if(key_in_char[i*2] < 9)
  7.         {
  8.                 key_in_char[i*2] += 0x30;               // Es un numero, si habia un 0x5 ahora hay un '5'
  9.         }
  10.         else
  11.         {
  12.                 key_in_char[i*2] += 0x37;               // Es una letra si habia una 0xB ahora hay una 'B'
  13.         }
  14.  
  15.         key_in_char[(i*2)+1] = key[i] & 0x0F;           // Nibble bajo, corresponder a la letra de la derecha
  16.  
  17.         if(key_in_char[(i*2)+1] < 9)
  18.         {
  19.                 key_in_char[(i*2)+1] += 0x30;           // Es un numero, si habia un 0x0 ahora hay un '0'
  20.         }
  21.         else
  22.         {
  23.                 key_in_char[(i*2)+1] += 0x37;           // Es una letra si habia un 0xF ahora hay una 'F'
  24.         }
  25.  
  26. }

Se puede rebuscar mejor para que funcione con los PIC, pero queria que el codigo sea entendible, si lo deseas pienso que mas optimizado seria algo asi:

Código: C
  1. char    key_in_char[sizeof(key)*2];
  2. char    *ptr = key_in_char;
  3.  
  4. for( i=0; i < sizeof(key) ; ++i)
  5. {
  6.         *ptr = ( (key[i]<<4) || (key[i]>>4) ) & 0x0F;           // SWAPF + ANDLW -> MOVWF Indirecto , 3 instrucciones deberia usar
  7.         if(*ptr > 9)                                            // SUBWF BTFSS, 3 instrucciones
  8.         {
  9.                 *ptr += 0x7;                                    // 2 instrucciones MOVLW ADDWF
  10.         }
  11.         *ptr += 0x30;                                           // 2 instrucciones o 3 si se cuenta lo anterior
  12.         ++ptr;
  13.  
  14.         *ptr = key[i] & 0x0F;                                   // 2 instrucciones
  15.         if(*ptr > 9)
  16.         {
  17.                 *ptr += 0x7;
  18.         }
  19.         *ptr += 0x30;
  20.         ++ptr;
  21.  
  22. }

En fin ese no era el tema. Pero al final de este codigo, key_in_char[] tendria este valor:

Código: C
  1. key_in_char[12] = {'0','0','0','0','0','0','B','8','C','5','2','C'};

El cual podrias comparar ahora si con el mismo codigo que tenias antes, recordando modificar que ahora tenes que comparar 12 valores y no 6.

EDIT: Arreglado los valores a ser sumados.
« Última modificación: 26 de Marzo de 2016, 05:07:31 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:comparar dos array
« Respuesta #11 en: 26 de Marzo de 2016, 01:27:03 »
Pensemos un poco, un Hexadecimal tiene 16 valores, de 0 a 9 y A a F.
.....

Wowww genial,  pero me toco cambiar 41 por 37... lo deduci de la tabla ascii.


cuando la conversión es un numero, no hay problema pero cuando es una letra se convertía un valor ascii mayor, por ejemplo
char key[6] = {0x00,0x00,0x00,0xB8,0xC5,0x2C};

cuando llega a 'B'  , B+41= 4C  = 'L', lo mismo sucede con 'C'  C+41=4D= 'M'

A+37=41 = 'A'
B+37=42 = 'B'
C+37=43 = 'C'

Como siempre, eres un maestro. muchas gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:comparar dos array
« Respuesta #12 en: 26 de Marzo de 2016, 05:06:30 »
Si me confundi con el tema de las letras, es 0x37 que hay que sumarle, corrigo los anteriores codigos por si alguiene lo necesita.