imagen.png
Pero que tal si es formato .jpg o incluso un vídeo o audio,esto no es muy importante,para el usuario,pero a la hora de programar algo de bajo nivel o incluso de nivel usuario,por ejemplo una GUI si no seleccionamos el archivo correcto tendríamos un error,por ejemplo un reproductor de música o vídeo que le mandemos una imagen como ruta,esto causaría el cierre de la aplicación o en sistemas débiles el congelamiento de todo el sistema.
Bueno también en ocasiones tenemos archivos sin extensión,con el nombre por ejemplo:
archivo
En Unix si tiene permisos de ejecución lo mas seguro es que sea un programa,pero en ocasiones son archivos multimedia,como dije el usuario no se debe preocupar por esto ya que si tienen un explorador potente como por ejemplo Dolphin de KDE el lee los Magic Numbers y si tenemos una imagen sin extensión la detecta:
Como vemos detecta los archivos,pero si quisiéramos crear un explorador necesitaríamos usar números mágicos y no filtro por extensión.
En esta ocasión vamos a hacer este trabajo usando C,ya que lo vamos a usar en el sistema,si lo quisiéramos usar por ejemplo en Android lo podemos hacer en Java o usando el NDK.
Bien vamos a leer el archivo en modo binario y vamos a leer los primeros 8 bytes que serian 8 char,los primeros 8 char del archivo,luego los vamos a imprimir en pantalla,hay caracteres Hex que no se pueden imprimir asi que solo imprimiremos los que se puedan.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <stdio.h> #include <ctype.h> #define BYTES 8 // Numero de bytes void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre int main(int argv,char *argc[]) { if (argv>1) readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento return 0; } void readFile(char *file) { char nums[BYTES]; // Definimos un array de n bytes int i; FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura fread(nums,1,BYTES,fp); // Lemos los primeros n bytes for (i=0;i<BYTES;i++) // Recorremos el array { if (isgraph(nums[i])) // Si se puede imprimir printf("Nums %c\n",nums[i]); // Lo imprimimos } fclose(fp); return; } |
Ahora vamos a usarlo:
Como vemos en el primer archivo use una imagen png con extensión jpg y no hubo problema al detectar el tipo de archivo,en el segundo use un .pdf y efectivamente es .pdf.
Algunos archivos no simplemente van a decir PNG o PDF,por ejemplo el numero magico de un mp3 es ID3:
Algunos números mágicos los podemos encontrar aquí:
https://en.wikipedia.org/wiki/List_of_file_signatures
Y eso nos sirve para definir un array de comprobacion,por ejemplo para el mp3,seria en HEX:
49 44 33
Que solo serian 3 bytes,3 char:
Veamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include <stdio.h> #include <ctype.h> #define BYTES 8 // Numero de bytes typedef enum _boolean {FALSE,TRUE} boolean; // Tipo boolean void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre boolean isMp3(char *file); // Funcion para saber si es mp3 int main(int argv,char *argc[]) { if (argv>1){ readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento if(isMp3(argc[1])) // Vemos si es mp3 printf("%s es mp3\n",argc[1]); else printf("%s no es mp3\n",argc[1]); } return 0; } boolean isMp3(char *file) { const int lenNum = 3; // Numero de Bytes char nums[lenNum]; // array que contendra los numero magicos char id[] = {0x49,0x44,0x33}; // Numeros magicos del mp3 int i; boolean flag = TRUE; // Este sera el valor de retorno FILE *fp = fopen(file,"rb"); // Abrimos el archivo fread(nums,1,lenNum,fp); // Lemos los primeros 3 bytes for (i=0;i<lenNum;i++) // Recorremos el array { if(nums[i] != id[i]) // Si no son iguales { flag = FALSE; // Cambiamos el valor de retorno break; // rompemos el bucle } } fclose(fp); // Cerramos el archivo return flag; // Regresamos el valor } void readFile(char *file) { char nums[BYTES]; // Definimos un array de n bytes int i; FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura fread(nums,1,BYTES,fp); // Lemos los primeros n bytes for (i=0;i<BYTES;i++) // Recorremos el array { if (isgraph(nums[i])) // Si se puede imprimir printf("Nums %c\n",nums[i]); // Lo imprimimos } fclose(fp); return; } |
Con esa funcion que definimos logramos saber si un archivo es mp3,igual lo podemos hacer con un mp4 solo que wikipedia nos dice que hay dos posibilidades,veamos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include <stdio.h> #include <ctype.h> #define BYTES 8 // Numero de bytes typedef enum _boolean {FALSE,TRUE} boolean; // Tipo boolean void readFile(char *file); // Funcion que leera el archivo,le pasamos el nombre boolean isMp3(char *file); // Funcion para saber si es mp3 boolean isMp4(char *file); int main(int argv,char *argc[]) { if (argv>1){ readFile(argc[1]); // Le pasamos el nombre del archivo que indiquemos en el argumento if(isMp4(argc[1])) // Vemos si es mp3 printf("%s es mp4\n",argc[1]); else printf("%s no es mp4\n",argc[1]); } return 0; } boolean isMp4(char *file) { const int lenNum = 4; // Numero de Bytes char nums[lenNum]; // array que contendra los numero magicos char id1[] = {0x22,0x67,0x70,0x35}; // Numeros magicos del mp4 char id2[] = {0x66,0x74,0x79,0x70}; // Numeros magicos del mp4(otra posibilidad) int i; boolean flag = TRUE; // Este sera el valor de retorno FILE *fp = fopen(file,"rb"); // Abrimos el archivo fread(nums,1,lenNum,fp); // Lemos los primeros 4 bytes para probar el primer id for (i=0;i<lenNum;i++) // Recorremos el array { if(nums[i] != id1[i]) // Si no son iguales { flag = FALSE; // Cambiamos el valor de retorno break; // rompemos el bucle } } if (flag == FALSE) // Si la bandera es FALSE probamos el siguiente id { flag = TRUE; // Cambiamos el flag a TRUE fseek( fp, 4, SEEK_SET ); // Nos movemos 4 bytes a la derecha ya que no nos sirven estos : 00 00 00 nn fread(nums,1,lenNum,fp); // Lemos los segundos 4 bytes for (i=0;i<lenNum;i++) // Recorremos el array { if(nums[i] != id2[i]) // Si no son iguales { flag = FALSE; // Cambiamos el valor de retorno break; // rompemos el bucle } } } fclose(fp); // Cerramos el archivo return flag; // Regresamos el valor } boolean isMp3(char *file) { const int lenNum = 3; // Numero de Bytes char nums[lenNum]; // array que contendra los numero magicos char id[] = {0x49,0x44,0x33}; // Numeros magicos del mp3 int i; boolean flag = TRUE; // Este sera el valor de retorno FILE *fp = fopen(file,"rb"); // Abrimos el archivo fread(nums,1,lenNum,fp); // Lemos los primeros 3 bytes for (i=0;i<lenNum;i++) // Recorremos el array { if(nums[i] != id[i]) // Si no son iguales { flag = FALSE; // Cambiamos el valor de retorno break; // rompemos el bucle } } fclose(fp); // Cerramos el archivo return flag; // Regresamos el valor } void readFile(char *file) { char nums[BYTES]; // Definimos un array de n bytes int i; FILE *fp = fopen(file,"rb"); // Abrimos el archivo en modo binario y lectura fread(nums,1,BYTES,fp); // Lemos los primeros n bytes for (i=0;i<BYTES;i++) // Recorremos el array { if (isgraph(nums[i])) // Si se puede imprimir printf("Nums %c\n",nums[i]); // Lo imprimimos } fclose(fp); return; } |
Así podemos crear un biblioteca con todas las extensiones para usarlas en un programa.
Eso es todo :D
No hay comentarios.:
Publicar un comentario
Los comentarios serán revisados antes de ser publicados.