Bienvenido a los foros de Perl en Español, maschino2.
El problema que veo es que estás haciendo una conversión a cadena de caracteres, en las líneas 47 a 49, por medio de la función uc(). Te vale con cambiarla por la función hex() para que todo funcione. Esa función está indicando que lo que contiene las variables $byte está en hexadecimal y queremos pasarlo a entero. Así, la operación matemática del
xor, a continuación, funcionará bien.
Esta es otra solución, usando datos puramente binarios, usando chr() y ord() para hacer la conversión de entero a valor entero binario.
Using perl Syntax Highlighting
#!/usr/bin/perl
# Valores fijos para el cálculo del checksum
$byte1 = chr 0x09;
$byte2 = chr 0x02;
$byte6 = chr 0x03;
$byte7 = chr 0xBC;
$byte8 = chr 0xFF;
$byte9 = chr 0x7E;
# Damos la ubicación del fichero SecurityCodes y lo abrimos para leer
$Fichero_SecurityCodes="Serial.csv";
open (ENTRADA,"<$Fichero_SecurityCodes") or die "ERROR: No puedo abrir el fichero $Fichero_SecurityCodes";
# Damos la ubicacion del fichero de salida y lo abrimos para escribir
$Fichero_Checksum="Salida.csv";
open (SALIDA,">$Fichero_Checksum") or die "ERROR: No puedo abrir el fichero $Fichero_Checksum";
# Metemos en tabla el fichero
# Y usamos las entradas lista[0] para el nº de serie
print "Nº serie hex bit1 bit2 bit3 cksum\n";
while (<ENTRADA>)
{
@lista = split q[;], $_;
# Pasamos a hexadecimal el numero de serie
$hexval = sprintf("%06X", $lista[0]);
# Dividimos el hexadecimal en 3 bytes para usarlos posteriormente
$byte3 = chr hex substr $hexval, 0, 2;
$byte4 = chr hex substr $hexval, 2, 2;
$byte5 = chr hex substr $hexval, 4, 2;
# Ejecutamos para conseguir el Checksum
$res1 = $byte1 ^ $byte2 ^ $byte3 ^ $byte4 ^ $byte5 ^ $byte6 ^ $byte7 ^ $byte8 ^ $byte9;
# Convertimos el valor del checksum que sale en decimal a hexadecimal
$decval = ord $res1;
# Sacamos por pantalla lo que nos interesa
# print "\n";
# print "El nº de serie es $lista[0]\n";
# print "En hexadecimal $hexval \n";
# printf "El byte1 es %02X %08b\n", ord($byte1), ord($byte1);
# printf "El byte2 es %02X %08b\n", ord($byte2), ord($byte2);
# printf "El byte3 es %02X %08b\n", ord($byte3), ord($byte3);
# printf "El byte4 es %02X %08b\n", ord($byte4), ord($byte4);
# printf "El byte5 es %02X %08b\n", ord($byte5), ord($byte5);
# printf "El byte6 es %02X %08b\n", ord($byte6), ord($byte6);
# printf "El byte7 es %02X %08b\n", ord($byte7), ord($byte7);
# printf "El byte8 es %02X %08b\n", ord($byte8), ord($byte8);
# printf "El byte9 es %02X %08b\n", ord($byte9), ord($byte9);
# printf "El checksum normal es: %d \n" , $decval;
# printf "El checksum en Hexadecimal es: %02X\n", $decval;
# printf "El checksum en Hexadecimal es: %0#X\n", $decval;
printf "%07d %6s %02X %02X %02X %02X\n", $lista[0], $hexval, ord($byte3), ord($byte4), ord($byte5), $decval;
}
close ENTRADA;
close SALIDA;
Coloreado en 0.005 segundos, usando
GeSHi 1.0.8.4
Estos son los cambios principales:
* hacemos uso de la función
ord() para transformar un valor entero binario a entero decimal
* hacemos uso de la función
chr() para transformar un entero decimal a entero binario.
Las líneas que definen a los bytes 1, 2, y 6 al 9, son de esta manera:
$byte1 = chr 0x09;en la que estamos pasando un valor entero (en formato de Perl) a entero binario. Ahora, $byte1 sí que guarda la representación binaria de un nueve. Si no hiciéramos esto, guardaría un 9 como entero escalar de Perl.
Ahora ya podemos realizar las operaciones binarias con
xor.
En cambio, cuando necesitemos sacar la representación decimal de ese valor, necesitaremos usar la función ord(), como en el caso de los printf(). Primero pasamos ese número 9 almacenado de forma binaria a un número decimal 9 con la ayuda de ord(). Y luego printf() lo transforma al formato visual que necesitamos.