Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8862[/thread]

PHP script in perl umsetzen



<< |< 1 2 >| >> 11 Einträge, 2 Seiten
thoweiss
 2007-03-22 14:10
#75247 #75247
User since
2007-03-22
6 Artikel
BenutzerIn
[default_avatar]
Hallo alle miteinander - ich bin der neue ;-)

Ich möchte dieses PHP-Script in perl umsetzen:
Es handelt sich um eine CRC-Prüfung für ein hausautomatisirungsinterface von ELV (HS485PCI)

aus dem befehl fe0401 muss sich die Checksumme bed2 ergeben (beides Hex)

das PHP-Script funzt auch, aber leider das perlscript nicht so ganz, da kommt immer etwas anderes raus.

Achja, use bigint; habe ich beim perlscript aktiviert.

Kann jemand helfen??

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
$strToSend = "\xfe\x04\x01";
$CRC16 = GetCRC16($strToSend. "\x00\x00"); // ergibt "BED2"
echo "Checksum 1: ". sprintf("%X", $CRC16). "\r\n";


$strReceived = "\xfe\x04\x01\xbe\xd2";
$CRC16 = GetCRC16($strReceived); // ergibt 0
echo "Checksum 2: ". sprintf("%X", $CRC16). "\r\n";


function GetCRC16($s)
{
$CRCreg = 0xffff00;
for ($cp=0; $cp<strlen($s); $cp++)
{
$CRCreg |= ord($s[$cp]);
for ($bp=0; $bp<8; $bp++)
{
$CRCreg <<= 1;
if ($CRCreg & 0x1000000) $CRCreg ^= 0x100200; // hier ist das Polynom 0x1002 enthalten
$CRCreg &= 0xffffff;
}
}
return $CRCreg >> 8;
}
?>


ich habe folgendes Perl-scrip daraus gestrickt...:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
my $send_cmd;
my $strToSend;
my $strReceived;
my $CRC16;
my $CRCreg;
my $cp;
my $bp;
my @s;
my $s;

sub testcrc {
#Beim Senden ist zu beachten, dass für die Berechnung der Checksumme
#an den String noch zwei Null-Bytes ("\x00\x00") anzuhängen sind.
#Die berechnete Checksumme wird dann anstelle dieser beiden Null-Bytes gesendet.
#("\x00\x00")
$strToSend = "\0xfe\0x04\0x01";
$CRC16 = GetCRC16($strToSend. 0x0000); # ergibt / gives "BED2"
print "Checksum 1: ". sprintf("%X", $CRC16). "\r\n";

$strReceived = "\0xfe\0x04\0x01\0xBE\0xD2";
$CRC16 = GetCRC16($strReceived); # ergibt / gives "0"
print "Checksum 2: ". sprintf("%X", $CRC16). "\r\n";
goto MENUE;
}

sub GetCRC16{

$CRCreg = 0xffff00;
$s = $_[0];

@s=split(//,$s);
for ($cp=0; $cp<length($s); $cp++){
$CRCreg |= ord($s[$cp]);
for ($bp=0; $bp<8; $bp++){
$CRCreg <<= 1;
if ($CRCreg & 0x1000000){
$CRCreg ^= 0x100200; # hier ist das Polynom 0x1002 enthalten
$CRCreg &= 0xffffff;
}
}
}
return $CRCreg >> 8;

}
\n\n

<!--EDIT|thoweiss|1174565986-->
renee
 2007-03-22 15:05
#75248 #75248
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Schau Dir mal das Modul CPAN:Digest::CRC an. Dort gibt es schon eine fertige Routine für die Erzeugung von CRCxx-Zahlen.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
GwenDragon
 2007-03-22 15:34
#75249 #75249
User since
2005-01-17
14578 Artikel
Admin1
[Homepage]
user image
Das ist aber nicht die gleiche CRC16-Routine wie die aus dem Modul Digest::CRC!


So sollte das Skript gehen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/perl

use strict;
use warnings;

my $strToSend = "\xfe\x04\x01";
my $CRC16 = GetCRC16($strToSend. "\x00\x00"); # ergibt "BED2"
print "Checksum 1: ". sprintf("%X", $CRC16). "\n";


my $strReceived = "\xfe\x04\x01\xbe\xd2";
$CRC16 = GetCRC16($strReceived); # ergibt 0
print "Checksum 2: ". sprintf("%X", $CRC16). "\n";

sub GetCRC16 {
   my $s = shift;
   
   my $CRCreg = 0xffff00;
   
   for (my $cp=0; $cp<length($s); $cp++) {
    $CRCreg |= ord( substr($s,$cp,1) );
    
    for (my $bp=0; $bp<8; $bp++) {
        $CRCreg <<= 1;
        if ($CRCreg & 0x1000000) {
        $CRCreg ^= 0x100200; # hier ist das Polynom 0x1002 enthalten
        }
        $CRCreg &= 0xffffff;
    }
   }
   return $CRCreg >> 8;
}

1;
\n\n

<!--EDIT|GwenDragon|1174570576-->
die Drachin Gwendolyn
thoweiss
 2007-03-22 17:05
#75250 #75250
User since
2007-03-22
6 Artikel
BenutzerIn
[default_avatar]
Super! es geht!!


Danke und Gruß,

thorsten.\n\n

<!--EDIT|thoweiss|1174583689-->
thoweiss
 2007-03-23 08:37
#75251 #75251
User since
2007-03-22
6 Artikel
BenutzerIn
[default_avatar]
Jetzt habe ich ein neues Problem...
Die CRC-Berechnung funktioniert zwar, aber ich habe jetzt ein problem meine datem im richtigen format zu wandeln.

Das CRC-script erwartet ja so etwas:

$strToSend = "\xfe\x04\x01"

Ich bekomme von meinem interface dieses:
my $hexdata = "fe0401";

Ich habe die daten mit folgendem script versucht zu wandeln:

Ausgabe auf der kommandozeile:

misterhouse:/home/misterhouse/misterhouse-2.102/bin# perl unpack.pl
\xfe\x04\x01\x00\x00 Das ist das ergebnis der Umwandlung
Checksum A: c906 Die checksumme meiner daten
þ Das ist Print $strToSend
Checksum 1: bed2 Und die korrekte checksumme...


warum ist mein \xfe\x04\x01\x00\x00 nicht identisch mit
(Die beiden null bytes habe ich hier vorher angehängt und den sub aufruf entsprechend angepasst)


$strToSend = "\xfe\x04\x01";
Das sind doch beides strings, oder?

Interpretiert perl $strToSend = "\xfe\x04\x01"; als hex-daten??

Wie wandel ich meine \xfe\x04\x01 in \xfe\x04\x01???


Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/perl

use strict;
use warnings;

my $hexdata = "fe0401";

my @split = unpack( "A2" x (length($hexdata)/2), $hexdata );

my $strToSend = ("\\x". join ("\\x",@split)."\\x00\\x00");

print $strToSend,"\n";
my $CRC16 = GetCRC16($strToSend); # ergibt "BED2"
print "Checksum A: ". sprintf("%x", $CRC16). "\n";


$strToSend = "\xfe\x04\x01";
print $strToSend,"\n";

$CRC16 = GetCRC16($strToSend. "\x00\x00"); # ergibt "BED2"
print "Checksum 1: ". sprintf("%x", $CRC16). "\n";

sub GetCRC16 {
my $s = shift;

my $CRCreg = 0xffff00;

for (my $cp=0; $cp<length($s); $cp++) {
$CRCreg |= ord( substr($s,$cp,1) );

for (my $bp=0; $bp<8; $bp++) {
$CRCreg <<= 1;
if ($CRCreg & 0x1000000) {
$CRCreg ^= 0x100200; # hier ist das Polynom 0x1002 enthalten
}
$CRCreg &= 0xffffff;
}
}
return $CRCreg >> 8;
}

1;
:(
docsnyder
 2007-03-23 09:38
#75252 #75252
User since
2005-09-08
300 Artikel
BenutzerIn
[Homepage] [default_avatar]
@thoweiss

Wilkommen im Club! (von PHP halte ich nicht wirklich viel ;o)

Versuch's mal damit:
Code: (dl )
$hexdata =~ s/(..)/\\x$1/g;


Gruss, Doc
thoweiss
 2007-03-23 10:38
#75253 #75253
User since
2007-03-22
6 Artikel
BenutzerIn
[default_avatar]
Danke,

aber kannst Du mir kurz erläutern was der codeschnipsel tut?
(ich habs noch nicht so mit reg-exp, ist doch eine, oder?):p

Gruß,
Thorsten.
renee
 2007-03-23 10:42
#75254 #75254
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Das nimmt immer zwei Zeichen und ersetzt es durch "\xZeichen".

So wird aus "AB" ein "\xAB" und aus "ABCD" ein "\xAB\xCD"...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
thoweiss
 2007-03-23 17:45
#75255 #75255
User since
2007-03-22
6 Artikel
BenutzerIn
[default_avatar]
So langsam werde ich wuschig!!

wenn ich meine bytes als array übergebe, mit pack in binäre daten verwandle und dann an die CRC routine übergebe, dann geht es!!

Aber wie zum geier wandel ich einen String "fe0401" in ein hex-array mit den werten my @bytes = (0xFE, 0x04, 0x01); ??

Vermutlich ist es so einfach, aber ich sehe es im moment nicht...

Ich mach jetzt erstmal pause....

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/perl

use strict;
use warnings;


my @bytes = (0xFE, 0x04, 0x01); #command for get software version from HS485PCI

my $cmd = pack("C*", @bytes);
print $cmd,"\n";

my $CRC16 = GetCRC16($cmd. "\x00\x00"); # ergibt "BED2"
print "Checksum A: ". sprintf("%x", $CRC16). "\n";


my $strToSend = "\xfe\x04\x01";
print $strToSend,"\n";

$CRC16 = GetCRC16($strToSend. "\x00\x00"); # ergibt "BED2"
print "Checksum 1: ". sprintf("%x", $CRC16). "\n";

sub GetCRC16 {
my $s = shift;

my $CRCreg = 0xffff00;

for (my $cp=0; $cp<length($s); $cp++) {
$CRCreg |= ord( substr($s,$cp,1) );

for (my $bp=0; $bp<8; $bp++) {
$CRCreg <<= 1;
if ($CRCreg & 0x1000000) {
$CRCreg ^= 0x100200; # hier ist das Polynom 0x1002 enthalten
}
$CRCreg &= 0xffffff;
}
}
return $CRCreg >> 8;
}

1;
\n\n

<!--EDIT|thoweiss|1174664806-->
PerlProfi
 2007-03-23 20:18
#75256 #75256
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
[quote=thoweiss,23.03.2007, 16:45]Aber wie zum geier wandel ich einen String "fe0401" in ein hex-array mit den werten my @bytes = (0xFE, 0x04, 0x01); ??[/quote]
Das geht z.B. so:
Code: (dl )
1
2
3
my $str = 'fe0401';
my @arr = $str =~ /([0-9a-f]{2})/g;
map { $_ = hex $_ } @arr;


MfG\n\n

<!--EDIT|PerlProfi|1174674035-->
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2007-03-22 14:10.