Mie Jun 13, 2007 10:44 am
|
 |
alberto_lsa
Perlero Nuevo

|
Registrado: 13 Jun 2007
Mensajes: 5
|
|
| Lectura de binario desde Perl |
|
|
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! |
|
|
|
Mie Jun 13, 2007 12:50 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 478
Ubicación: Frente al monitor
|
|
|
|
Mie Jun 13, 2007 4:04 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
|
|
|
|
|
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()?). |
|

Mie Jun 13, 2007 4:17 pm
|
 |
alberto_lsa
Perlero Nuevo

|
Registrado: 13 Jun 2007
Mensajes: 5
|
|
|
|
|
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... |
|

Mie Jun 13, 2007 4:20 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 478
Ubicación: Frente al monitor
|
|
|
|
|
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...)? |
|

Mie Jun 13, 2007 4:57 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
|
|
|
|
|
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 |
|
Mie Jun 13, 2007 5:00 pm
|
 |
alberto_lsa
Perlero Nuevo

|
Registrado: 13 Jun 2007
Mensajes: 5
|
|
|
|
|
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... |
|
Mie Jun 13, 2007 5:09 pm
|
 |
alberto_lsa
Perlero Nuevo

|
Registrado: 13 Jun 2007
Mensajes: 5
|
|
|
|
|
Buenas... ahora consigo algo más, pero algunos con signo negativo ( y todos deben ser positivos...), ¿cómo los considero unsigned?
GRACIAS! |
|
Mie Jun 13, 2007 5:10 pm
|
 |
explorer
Moderador

|
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
|
|
|
|
|
Si estás en Linux, hazle un
| Código: |
| hexdump -C fichero|head |
y saldrá el volcado hexadecimal de lor primeros bytes del fichero. |
|
Mie Jun 13, 2007 5:24 pm
|
 |
alberto_lsa
Perlero Nuevo

|
Registrado: 13 Jun 2007
Mensajes: 5
|
|
|
|
|
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. |
|
Mie Jun 13, 2007 5:35 pm
|
 |
explorer
Moderador

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

|
Registrado: 24 Jul 2005
Mensajes: 4086
Ubicación: Valladolid, España
|
|
|
|
|
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; |
|
Powered by phpBB © 2001, 2005 phpBB Group
|