Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Lectura de binario desde Perl

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio
Mensaje Mie Jun 13, 2007 10:44 am
alberto_lsa
Perlero Nuevo
Perlero Nuevo
Registrado: 13 Jun 2007
Mensajes: 5
Lectura de binario desde Perl Responder citando

Hola:

¡Tengo un problema bastante urgente! Tengo un archivo binario en el cual debo acceder y coger 8 bytes.

Estos 8 bytes los tengo que convertir a un número decimal... ¿Cómo lo hago? Estoy probando de mil formas y no hay manera...

¡Gracias!
Mensaje Mie Jun 13, 2007 12:50 pm
creating021
Vive para Perl en Español
Vive para Perl en Español
Registrado: 23 Feb 2006
Mensajes: 478
Ubicación: Frente al monitor
Responder citando

Perl:
#!/usr/bin/env perl
use strict;

open FL, "archivo.out" or die "Arghhh!: $!\n";
binmode FL;
my $data;
read(FL, $data, 8);
foreach my $chr ( split //, $data ){
 printf "HexNo=0x%x\n",oct($chr);
}
close FL;
Mensaje Mie Jun 13, 2007 4:04 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
Responder citando

Bienvenido a los foros de Perl en Español.

Pero, ¿en qué formato están los 8 números binarios?

¿little-endian o big-endian?

Y me parece que la solución de creating021 no es ni solución (¿Pintar valores hexadecimales de los valores decimales de cada byte creyendo que están en formato octal? ¿No habrá querido usar la función ord()?).
Mensaje Mie Jun 13, 2007 4:17 pm
alberto_lsa
Perlero Nuevo
Perlero Nuevo
Registrado: 13 Jun 2007
Mensajes: 5
Responder citando

Hola:

Pues creo que la lectura es de menos significativo a más significativo (es decir, de los 8 caracteres, el de la izda. o el primero que se lee es el que menos peso tiene).

El caso que intento leer carácter a carácter o de 8 en 8, y al pintar por pantalla o pasarlo a otra función el resultado obtenido es siempre 0. No sé cómo tratar lo que leo desde el archivo (no sé si lo leo bien) y tampoco dónde guardar la información (si es necesario alguna variable especial) o así...

¡Una ayudita!

PD: Muchas gracias por la bienvenida...
Mensaje Mie Jun 13, 2007 4:20 pm
creating021
Vive para Perl en Español
Vive para Perl en Español
Registrado: 23 Feb 2006
Mensajes: 478
Ubicación: Frente al monitor
Responder citando

Laughing Oops, decimal no hexa:

Perl:
#!/usr/bin/env perl
use strict;

open FL, "archivo.out" or die "Arghhh!: $!\n";
binmode FL;
my $data;
read(FL, $data, 8);
my @decimales = unpack("c*", $data);
close FL;
print "Los decimales son:\n".(join "\t", @decimales)."\n";

¿Cómo puede influir eso de big y little endian (yo se que es pero...)?
Mensaje Mie Jun 13, 2007 4:57 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
Responder citando

Sería interesante que mostraras lo que tienes hecho.

Supongamos que estás en una máquina little-endian.

Una forma de leerlo es parecido a como te muestra creating021:

Código:
* leer los 8 bytes
* con el split // podemos ir de carácter en carácter (otra forma sería usando la función substr();)
* Usar las matemáticas para obtener el número decimal:
 n = n * 256 + ord($caracter);

El problema es que el número desborda la representación normal de un entero, por lo que estaremos obligados a usar algo como use bigint;.

Ultima edición por explorer el Mie Jun 13, 2007 5:06 pm, editado 1 vez
Mensaje Mie Jun 13, 2007 5:00 pm
alberto_lsa
Perlero Nuevo
Perlero Nuevo
Registrado: 13 Jun 2007
Mensajes: 5
Responder citando

Pues no consigo más que obtener 0s todo el rato...

Os subiría el archivo, a ver si conseguís algo, pero no sé si le vasia hacer mucho caso...
Mensaje Mie Jun 13, 2007 5:09 pm
alberto_lsa
Perlero Nuevo
Perlero Nuevo
Registrado: 13 Jun 2007
Mensajes: 5
Responder citando

Buenas... ahora consigo algo más, pero algunos con signo negativo ( y todos deben ser positivos...), ¿cómo los considero unsigned?

GRACIAS!
Mensaje Mie Jun 13, 2007 5:10 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
Responder citando

Si estás en Linux, hazle un
Código:
hexdump -C fichero|head

y saldrá el volcado hexadecimal de lor primeros bytes del fichero.
Mensaje Mie Jun 13, 2007 5:24 pm
alberto_lsa
Perlero Nuevo
Perlero Nuevo
Registrado: 13 Jun 2007
Mensajes: 5
Responder citando

El código ahora mismo es:
Código:

use strict;

my @dec;
my $puntero;

open FL, "../Recorder_20070612_145112_Gps_streamOutput.idx" or die "Arghhh!: $!\n";
binmode FL;
my $data;
my $igg=0;
while ($igg<200){
read(FL, $data, 1,$igg);
@dec = unpack("C*", $data);
$puntero = @dec[0]+256*@dec[1]+256*256*@dec[2];
#print $puntero."\n";
#print @dec[0].@dec[1].@dec[2].@dec[3].@dec[4].@dec[5].@dec[6].@dec[7];
$igg++;
}
print "Los decimales son:\n".(join "\t", @dec)."\n";
#print @decimales[0]." ".@decimales[1];
close FL;


Por pantalla obtengo lo que quiero, pero cómo lo puedo obtener en una variable vector? con sprintf? Porque al usar @dec[0] ... @dec[7], siempre es 0.

buffffff.
Mensaje Mie Jun 13, 2007 5:35 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
Responder citando

@dec[0], ... @dec[7] es notación para el Perl6 Smile

Como supongo que estarás con el Perl5, escríbelos como
$dec[0], ... $dec[7].
Mensaje Mie Jun 13, 2007 5:46 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
Responder citando

Yo creo que estás cometiendo un error con la forma de usar read().

Estás usándolo así: read(FL, $data, 1,$igg); que quiere decir que del fichero abierto, lees 1 byte y lo guardas dentro de $data en una posición desplazada $igg.

Yo creo que te sobra la variable $igg en esa instrucción. Y en vez de leer de uno en uno, puedes probar a leer más bytes de golpe. Con unpack luego los desempaquetas y los metes en @dec;
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group