2013-06-12 3 views
0

Я пытаюсь создать контрольную сумму для протокола NEMA (протокол GPS), используя perl. Образец NEMA слово строка символов, как показано нижеКак сгенерировать контрольную сумму XOR для строки с использованием perl

$GPGLL,5300.97914,N,00259.98174,E,125926,A*28

Контрольная сумма рассчитывается, принимая XOR всех символов между $ и *. В этом предложении контрольная сумма является символьное представление шестнадцатеричного значения 28.

Я попытался следующие:

my $NMEA_word = 'GPGLL,5300.97914,N,00259.98174,E,125926,A'; 
my $uff = unpack('%8A*', $NMEA_word); 
print "Hexadecimal number: ", uc(sprintf("%x\n", $uff)), "\n"; 

Но это, кажется, не дает правильного значения. Просьба предложить то, что должно быть исправлено

ответ

4
my $uff; 
$uff ^= $_ for unpack 'C*', 'GPGLL,5300.97914,N,00259.98174,E,125926,A'; 
printf "Hexadecimal number: \U%x\n", $uff; 
__END__ 
Hexadecimal number: 28 
+0

Иногда я чувствую, что должна быть возможность upvote большее количество раз. Вы сохранили мой день – bubble

+2

нет необходимости в верхнем регистре, просто используйте '% X' вместо'% x' – ysth

1

unpack объекта для создания контрольной суммы добавляет значения поля вместе, в то время как вы хотите, то операция XOR.

Эта программа будет делать то, что вы просите.

use strict; 
use warnings; 

my $NMEA_word = 'GPGLL,5300.97914,N,00259.98174,E,125926,A'; 

printf "Hexadecimal number: %s\n", checksum($NMEA_word); 

sub checksum { 
    my ($string) = @_; 
    my $v = 0; 
    $v ^= $_ for unpack 'C*', $string; 
    sprintf '%02X', $v; 
} 

выход

Hexadecimal number: 28 
3

Более функционально,

use List::Util 'reduce'; 
sub checksum { 
    sprintf '%02X', ord reduce { our $a^our $b } split //, shift; 
} 
print checksum('GPGLL,5300.97914,N,00259.98174,E,125926,A'), "\n"; 
+1

- это 'our $ a' рекомендуемая практика? –

+0

Встроенная сортировка perl использует $ a и $ b и автоматически объявляет их, чтобы избежать ошибок только для использования только один раз, но сокращение не может этого сделать, поэтому вам нужно либо отключить предупреждение один раз, либо объявить их вручную. – ysth

Смежные вопросы