0

我正在尝试使用 perl 为 NEMA(GPS 协议)字生成校验和。示例 NEMA 字是如下所示的字符串

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

$校验和是通过对和之间的所有字符进行异或来计算的*。在这句话中,校验和是十六进制值 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

3 回答 3

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
于 2013-06-12T17:24:04.757 回答
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";
于 2013-06-12T17:53:46.787 回答
1

unpack生成校验和的工具字段值加在一起,而您想要然后异或。

该程序将按照您的要求进行。

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
于 2013-06-12T17:32:24.907 回答