Entrega final del proyecto semestral
Enviado por Israel Canino • 4 de Junio de 2017 • Tutorial • 2.385 Palabras (10 Páginas) • 150 Visitas
[pic 1]
ITESM-CEM
Sistemas Operativos
Entrega final del proyecto semestral
Profesor: Oscar Herrera
Fecha de entrega: 04 de mayo del 2017
Indicaciones
1. Introducción
En la Teoría de la Información de Shannon, se define la cantidad de información de un suceso si como I(si) = -log p(si) en donde p(si) es la probabilidad de ocurrencia de si, medida en bits cuando se usa logaritmo en base 2.
En la práctica, la probabilidad de un suceso o evento p(si) se estima mediante la frecuencia relativa fr(si) definida como fr(si) = f(si) / (f(si)) en donde f(si) es la frecuencia individual o número de veces que se repite el suceso si, y (f(si) es la suma de todas las frecuencias individuales de los n diferentes si.
La entropía o valor esperado de la información se define como H(S) = p(si) I(si) = - p(si) log p(si)
Una aplicación de esta teoría consiste en estimar la compresibilidad de un archivo, o de múltiples archivos, a los cuales se les calcula su entropía de los 256 códigos ASCII que se almacenan en esos archivos.
Problema.
Calcular la entropía de archivos TXT, MP3, JPG, o MPG contenidos en un directorio dado por el usuario, incluyendo el recorrido recursivo de sus subdirectorios.
Metodología.
Escribir un programa en lenguage C en ambiente GNU/Linux que:
1. Use funciones de acceso a la estructura de archivos y directorios de GNU/Linux.
2. Reciba un directorio como parámetro de entrada dado por el usuario.
3. Reciba una extensión de tipo de archivo a filtrar (TXT, MP3, JPG, MPG) o un asterisco * para filtrar a los cuatro tipos de archivos anteriores. Filtral se refiere a no tomar en cuenta archivos que no sean de estos tipos, por ejemplo, BMP, WAV, etc.).
4. Genere un histograma con las frecuencias de cada código ASCII (evento si) en base al número de veces que se repite cada
código (evento si) en todos los archivos filtrados
5. Calcule la entropía para los casos (TXT, MP3, JPG, MPG) o asterisco *
Código fuente.
- //Proyecto Final SO
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- double info[256];
- double info2[256];
- double Entropia = 0;
- char tipoArchivo[50];
- long hist[256];
- long total=0;
- char str[70];
- double proba[256];
- void *abre_carpeta(void *carp){
- char *name;
- name=(char *)carp;
- char bandera;
- DIR * directo;
- struct dirent *local_entry;
- char direccion[100];
- char noarch[200];
- int i=-1;
- int status;
- struct stat st;
- int pq;
- directo = opendir(name);
- if(directo==NULL){
- printf("Error\n");
- return 0;
- }
- pthread_t extra[256];
- uint8_t *buffer;
- FILE *fp;
- char *NombreArchivo;
- int q;
- while ((local_entry = readdir(directo))!= NULL) {
- NombreArchivo=local_entry->d_name;
- bandera=0;
- while(NombreArchivo[q]!='.'){
- q++;
- }
- if(tipoArchivo[0]=='*'&&(NombreArchivo[q+1]=='m'||NombreArchivo[q+1]=='t'||NombreArchivo[q+1]=='j')&&(NombreArchivo[q+2]=='p'
- ||NombreArchivo[q+2]=='x')&&(NombreArchivo[q+3]=='g'||NombreArchivo[q+3]=='3'||NombreArchivo[q+3]=='t')){
- bandera=1;
- }
- else{
- if(tipoArchivo[0]==NombreArchivo[q+1] && tipoArchivo[1]==NombreArchivo[q+2] && tipoArchivo[2]==NombreArchivo[q+3]){
- bandera=1;
- }
- else{
- bandera=0;
- }
- }
- if ((local_entry->d_name)[0]== q ==0||'.')
- {
- continue;
- }
- else if (local_entry->d_type == DT_REG && bandera) {
- memset(noarch,0,200);
- strcpy(noarch,local_entry->d_name);
- fp = fopen(noarch,"rb");
- if(fp==NULL){
- printf("%s imposible abrir !! \n", local_entry->d_name);
- continue;
- }
- else{
- fseek(fp,0,SEEK_END);
- pq=ftell(fp);
- rewind(fp);
- buffer=(char *)malloc((pq+1)*sizeof(uint8_t));
- fread(buffer,pq,1,fp);
- }
- fclose(fp);
- for (int z = 0; z < pq; ++z)
- {
- hist[buffer[z]]++;
- }
- memset(buffer,0,pq+1);
- free(buffer);
- stat(noarch, &st);
- total=total+st.st_size;
- printf("--%s: %li bytes\n",NombreArchivo,total);
- }
- else if (local_entry->d_type == (local_entry->d_name)[0] != '.' && DT_DIR ){
- memset(direccion,0,100);
- strcpy(direccion,name);
- strcat(direccion,str);
- strcat(direccion, local_entry->d_name);
- i++;
- status=pthread_create(&extra[i],NULL,abre_carpeta,(void *)direccion);
- usleep(100);
- pthread_join(extra[i], NULL);
- }
- q=0;
- }
- closedir(directo);
- return 0;
- }
- int main(int argc, char* argv[]){
- printf("Cual extension desea seleccionar? si quiere todas las extensiones ponga *: ");
- scanf("%s",tipoArchivo);
- strcpy(str, "/");
- abre_carpeta(argv[1]);
- long tot=0;
- for (int a = 0; a < 256; ++a){
- tot=tot+hist[a];
- }
- for (int b = 0; b < 256; ++b){
- proba[b]=(double)hist[b]/(double)tot;
- }
- for (int c = 0; c < 256; ++c){
- info[c]=log2(1/proba[c]);
- }
- for (int c = 0; c < 256; ++c){
- info2[c]=proba[c]*info[c];
- }
- for (int d = 0; d < 256; ++d){
- Entropia=Entropia+info2[d];
- }
- printf("\n la Entropia es: %f\n",Entropia);
- }
Doxygen
Se presenta el link de la documentación en Doxygen:
file:///D:/Desktop/Doxygen/html/globals_vars.html
Doxygen
Se presenta captura de pantalla de cálculo de entropía realizada al obtener los histogramas y probabilidad tal y como lo vimos en clase.
Calculo de entropía con .JPG.
[pic 2]
Conclusión
La teoría es muy diferente a la práctica, cuando vimos los temas en clase no se veía tan complicado la realización de este proyecto. Cuando se pasó a la etapa de crear el programa, me pareció un poco complicado el unir las prácticas de laboratorio realizadas previamente. Al momento de probar el programa en la consola ingresando la extensión de los tipos de archivos a generar histograma y calcular entropía, la consola regresaba errores de “core dumped”. Debido a esto perdí mucho tiempo y no logre probar correctamente mi programa más que con archivos jpg.
...