• Domingo 22 de Diciembre de 2024, 15:32

Autor Tema:  leer un fichero bit a bit  (Leído 5886 veces)

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
leer un fichero bit a bit
« en: Viernes 24 de Abril de 2009, 19:08 »
0
Buenas. He estado guiándome todo el rato con la documentación de python, y a la hora de abrir, leer, desplazarme y cerrar ficheros legibles no he tenido ningún problema. Pero ahora querría hacer una cosa un poco diferente. Sería cuestión de ver los bits del fichero, porque son datos no legibles.

He visto en la documentación que el único parámetro que le puedo pasar al .read() es el número de bytes, pero a partir de ahí ya no he encontrado nada útil.

A ver si me podeís ayudar, ya sea diciendome como leer bit a bit, o bien cómo tratar los bytes y poder ver el contenido no legible que haya cargado desde el fichero.

La verdad es que siempre he querido aprender hacer esto desde que empecé a dar mis primeros pasos con C, pero nunca me puse a mirar bien cómo iba, y aunque supiera hacerlo en C ahora... no creo que me fuera de mucha ayuda :S


Un saludo.

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
Re: leer un fichero bit a bit
« Respuesta #1 en: Sábado 25 de Abril de 2009, 12:17 »
0
Actalizo mi duda.

Creo que he conseguido "algo" xDD Lo que estoy intentando, en vez de leer bit a bit, es leer byte a byte, y hacer una conversion al byte para verlo como entero, y así podría sacar qué ceros y unos hay ahí, dentro del byte.

El código que tengo ahora mismo es el siguiente:


Código: Text
  1. import string
  2.  
  3. def leebits(nombre):
  4.     #"nombre" es el nombre del fichero en cuestion
  5.     f = file(nombre, 'r')
  6.    
  7.     n=0
  8.     f.seek(0,2)
  9.     tam = f.tell()
  10.     f.seek(0,0)
  11.     # en "tam" ya tengo el tamano en bytes del fichero para controlar cuando llego al final
  12.    
  13.     while (f.tell() < tam):
  14.         b = f.read(1)  # leo un solo byte
  15.         print string.atoi(b,10)
  16.         print 'n'
  17.    
  18.  
  19. print cuentabits("img.png")
  20.  

Teóricamente, estoy usando bien el método atoi, o al menos así es como yo entiendo que se usa. Aún así, no se me convierten bien a entero en base decimal. Si consiguiera hacer eso, el resto ya sería cuestión de convertir el número decimal a binario.

Es un proceso correcto, no?? A ver si voy a estar haciendo todo esto, y luego resulte que no funcione por algún motivo :S


Un saludo.

NRM

  • Miembro MUY activo
  • ***
  • Mensajes: 279
  • Nacionalidad: ar
    • Ver Perfil
    • http://www.narrowmind.com.ar
Re: leer un fichero bit a bit
« Respuesta #2 en: Lunes 27 de Abril de 2009, 05:10 »
0
podes probar con el código que esta a continuación.

Código: Python
  1. def binary(n):
  2.   """does not work on negative numbers! infinite loop"""
  3.   if(n < 0):
  4.     raise ValueError, "No definitive representation exists for negative integers"
  5.   out = ''
  6.   while(n):
  7.     out = str(n & 1) + out
  8.     n = n >> 1
  9.   return out
  10.  
  11. if __name__ == "__main__":
  12.   print binary(0xff)
  13.   print binary(0xde)
  14.   print binary(0xad)
  15.   print binary(0x52)
  16.   print binary(0x11)
  17.   print binary(0x01)
  18.  

tal vez si nos pudieras explicar por que necesitas leer bit a bit podríamos ayudarte a solucionar el problema de otra manera.

saludos

nrm

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
Re: leer un fichero bit a bit
« Respuesta #3 en: Lunes 27 de Abril de 2009, 09:21 »
0
Anda!! Más o menos comprendo ese código, y creo que eso es lo que buscaba (o parecido), pero lo tengo que probar en cuanto pueda (en este PC no está Python instalado).

Lo que pretendo leyendo el fichero bit a bit es hacer una pequeña parte de una aplicación que estoy escribiendo para Criptografía. Y en esta parte en concreto, lo que quiero hacer es leer un bit del archivo, y según sea 0 o 1, modificar el pixel de una imagen, o no modificarlo. Esto es básicamente para esconder esa información dentro de la imagen.

Entonces, lo que haré luego, es utilizar esta función confomre vaya leyendo bytes del archivo, y concatenar todos los valor que me devuelva para obtener una lista de todos los bits leidos.

Así luego me será más comodo, en vez de intentar hacerlo todo del tirón (aunque consumirá más memoria).


Luego os digo si me funciona. Gracias por la ayuda, NRM.

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
Re: leer un fichero bit a bit
« Respuesta #4 en: Lunes 27 de Abril de 2009, 10:37 »
0
Pues a ver, ya he probado ese codigo, y lo he amoldado un poquito para que en vez de hacerme un string, me haga una lista ^^

Pongo el código aquí y comento un error que me da y no sé cómo meterle mano:


Código: Text
  1. #!/usr/bin/env python
  2.  
  3. import string
  4.  
  5. def aBinario(n):
  6.         if(n<0):
  7.                 raise ValueError, "Entero negativo no valido"
  8.        
  9.         out=''
  10.         while(n):
  11.                 out = str(n & 1) + out
  12.                 n = n >> 1
  13.        
  14.         cad=[]
  15.         for i in range(len(out)):
  16.                 cad.expand(out[i])
  17.        
  18.         return cad
  19.  
  20.  
  21. def leefich(nomfich):
  22.         f = file(nomfich, 'r')
  23.        
  24.         n=0
  25.         f.seek(0,2)
  26.         tam = f.tell()
  27.         f.seek(0,0)
  28.         fich_cad=[]
  29.         while(f.tell()<tam):
  30.                 b = f.read(1)
  31.                 fich_cad.extend(aBinario(b))
  32.         return fich_cad
  33.  
  34.  
  35. if __name__ == "__main__":
  36.  
  37. datos = leefich('a.txt')
  38. print datos
  39.  

Eso me lanza el siguiente error en la línea 11:  TypeError: unsupported operand type(s) for &: 'str' and 'int'

Lo he intentado solucionar poniéndola así:

Código: Text
  1. out = str(int(n) & 1) + out
  2.  

He supuesto por el error que necesitaba que el operando fuera entero. Pero es que de esta forma me lanza este otro error: ValueError: invalid literal for int() with base 10: 'a'

Yo supongo que lo del 'a' será porque lo ha leido del fichero (a.txt solo contiene una a). Pero lo de la base 10... es que ya no sé que es eso, porque supuestamente, si le hago el casting a int, ya está en base 10, no??

RadicalEd

  • Moderador
  • ******
  • Mensajes: 2430
  • Nacionalidad: co
    • Ver Perfil
Re: leer un fichero bit a bit
« Respuesta #5 en: Lunes 27 de Abril de 2009, 14:17 »
0
Lo que quieres pegarle es a la esteganografía, revisa este post, está muy bueno y sencillo de entender.
Esteganografía
El pasado son solo recuerdos, el futuro son solo sueños

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
Re: leer un fichero bit a bit
« Respuesta #6 en: Lunes 27 de Abril de 2009, 16:25 »
0
Sí, está bien ese script. Pero lo que hace es abrir dos imágenes para tocarlas e introducir una en la otra. A mí lo que me interesa es meter otro tipo de información binaria, que ni si quiera tenga por qué ser texto. He ahí la necesidad de operar a nivel de bits.

DRiMeR

  • Nuevo Miembro
  • *
  • Mensajes: 22
    • Ver Perfil
    • http://www.informatizados.es
Re: leer un fichero bit a bit
« Respuesta #7 en: Lunes 27 de Abril de 2009, 19:16 »
0
Hola otra vez. Por fin lo he conseguido! Ya he conseguido pasar cualquier cosa a binario. Tal y como lo estaba haciendo, me servía sólo para caracteres, porque el string.atoi admite sólo bases desde 2 hasta 36, así que aunque me hubiera conformado con leer archivo que contuvieran texto, los símbolos (?, =, !, etc..) me hubieran fastidiado. El código me ha quedado así:

Código: Text
  1. def aBinario(n):
  2.     if(n<0):
  3.         raise ValueError, "Entero negativo no valido"
  4.    
  5.     cad=[]
  6.     b=struct.unpack('B', n)
  7.     b=b[0]
  8.     for i in range(8):
  9.         cad.append(b & 1)
  10.         b = b >> 1
  11.    
  12.     return cad
  13.  

El truco está en el unpack, y en que me lo convierte de forma que en vez de devolvermelo como una lista normal, he tenido que coger el primer elemento, que es donde pone el elemento convertido en forma de lista.


Muchas gracias por vuestra ayuda, como veis en el código, me ha ayudado bastante tener el código de NRM como guía (no tenía ni idea de que existiera el >> para mover los bits). Cuando termine la aplicación la colgaré por aquí :)


Un saludo.