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

XOR Checksum von HEX-Werten

Leser: 2


<< |< 1 2 >| >> 12 Einträge, 2 Seiten
rbach
 2009-02-16 14:19
#118894 #118894
User since
2009-02-16
2 Artikel
BenutzerIn
[default_avatar]
Hi Leute,

ich habe eine kleines Problem mit der Bildung einer XOR-Checksum. Es geht dabei um einen string, der dessen Zeichen in ihre HEX-Werte laut ASCII-Tabelle umgewandelt und anschließend für die Checksum mit XOR verknüpft werden.

Die Umwandlung klappt ohne Probleme. Aus meinen Teststring '51,8' wurde korrekt '35312c38'. Nun müssen alle Zeichen miteinander per XOR verknüpft werden.

Leider kommt es bei der Verknüpfung mit dem 'c' leider immer zu einen
falschen Ergebniss. Bei '6^c' müsste das Ergebniss 'A' sein und nicht '6'.
Die restlichen Ergebnisse stimmen aber alle.

Mein Code dazu:
Code: (dl )
1
2
3
4
5
6
7
8
  #in $ndata steht '35312c38'
$ndataxor = 0;
@array = split(//, $ndata);
foreach (@array)
{ print $ndataxor . " xor ". $_;
$ndataxor = $ndataxor^$_;
print " -> ". $ndataxor . "\n";
}


Meine Ausgabe (die Problemausgabe ist markiert):

0 xor 3 -> 3
3 xor 5 -> 6
6 xor 3 -> 5
5 xor 1 -> 4
4 xor 2 -> 6
6 xor c -> 6
6 xor 3 -> 5
5 xor 8 -> 13


Hat jemand einen Lösungsvorschlag? Bin für jede Hilfe sehr dankbar.

Grüße,
rbach
FoolAck
 2009-02-16 14:59
#118896 #118896
User since
2008-05-02
69 Artikel
BenutzerIn
[default_avatar]
Benutze bitte "use strict" und "use warnings". Die Warnung die du bekommen hättest, hätte dir bereits geholfen:
Quote
Argument "c" isn't numeric in bitwise xor (^)

Da du erwartest, dass '6^c==a' ist, gehe ich davon aus, dass du "c" als 12 und "a" als 10 interpretierst. Das sind für perl aber keine hex-Zahlen, sondern Strings, mit numerischem Wert von 0.
Willst du strings als hex interpretieren, nimmst du die Funktion hex:
Code: (dl )
1
2
3
4
5
6
7
8
9
use strict;
use warnings;
my $ndata = '35312c38';
my $ndataxor = 0;
for my $num (map { hex($_) } split //, $ndata) {
print "$ndataxor xor $num -> ";
$ndataxor ^= $num;
print "$ndataxor\n";
}


edit:
oder als hex angezeigt:
Code: (dl )
1
2
3
4
5
6
7
8
use strict;
use warnings;
my $ndata = '35312c38';
my $ndataxor = 0;
for my $num (map { hex } split //, $ndata) {
printf "%x xor %x -> %x\n", $ndataxor, $num, $ndataxor ^ $num;
$ndataxor ^= $num;
}
rbach
 2009-02-16 15:23
#118900 #118900
User since
2009-02-16
2 Artikel
BenutzerIn
[default_avatar]
danke! hat mir geholfen.
werds mir für die zukunft merken, das mit use warnings.
GwenDragon
 2009-02-16 15:23
#118902 #118902
User since
2005-01-17
14748 Artikel
Admin1
[Homepage]
user image
Durch dein split erzeugst du keine Hexzahlen sondern ASCII-Zeichen.
'c' hat den Hexwert: 0x63
'C' hat den Hexwert: 0x43
FoolAck
 2009-02-16 15:49
#118906 #118906
User since
2008-05-02
69 Artikel
BenutzerIn
[default_avatar]
Quote
Durch dein split erzeugst du keine Hexzahlen sondern ASCII-Zeichen.

Genauer gesagt nul-terminierte Char-Arrays.

Btw, wenn man nur strings xored, dann arbeitet perl mit den ascii-Werten:
Code: (dl )
perl -e 'print "CAPSAWAY" ^ "        "'

Jedoch muss man im Hinterkopf haben, dass diese Strings immernoch einen numerischen Wert von 0 haben. Bei numerischen Werten von Strings sollte man auch den Unterschied zwischen
Code: (dl )
perl -MDevel::Peek -e 'Dump "abc43"+0'

und
Code: (dl )
perl -MDevel::Peek -e 'Dump "43abc"+0'

beachten.

edit:
Quote
werds mir für die zukunft merken, das mit use warnings.

Ich hoffe doch das mit "use strict" auch, denn das ist mindestens genauso wichtig wie (wenn nicht sogar wichtiger als) "use warnings".
pq
 2009-02-18 12:35
#118956 #118956
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Crosspost!
http://forum.perl.de/bb/xor-checksum-von-hex-werte...

ist es soooo schwer, das kenntlich zu machen? url kopieren, als antwort ins jeweils andere
forum reinkopueren, fertig. wenn ich hilfe suche, gebe ich mir doch zumindest etwas mühe, oder?
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
LanX-
 2009-02-18 16:36
#118967 #118967
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
@pq: irgendwie erkennt man diese "Ego-Poster" doch am Stil und ignoriert sie gleich...
murphy
 2009-02-18 17:38
#118969 #118969
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
FoolAck+2009-02-16 14:49:25--
Quote
Durch dein split erzeugst du keine Hexzahlen sondern ASCII-Zeichen.

Genauer gesagt nul-terminierte Char-Arrays.
[...]


Perls Strings sind nicht nullterminiert, sondern haben eine Laengeninformation (was im uebrigen die wesentlich sinnvollere Speicherstruktur ist). Man kann in Perl ohne weiteres Nullzeichen in der Mitte eines Strings einbauen.
When C++ is your hammer, every problem looks like your thumb.
FoolAck
 2009-02-21 19:30
#119064 #119064
User since
2008-05-02
69 Artikel
BenutzerIn
[default_avatar]
Quote
Perls Strings sind nicht nullterminiert, sondern haben eine Laengeninformation (was im uebrigen die wesentlich sinnvollere Speicherstruktur ist). Man kann in Perl ohne weiteres Nullzeichen in der Mitte eines Strings einbauen.

Wow, danke fürs Umdrehen meiner Wörter. Wo genau habe ich "allgemeingültige" Aussage über perl-Strings losgelassen? Wo? Mit quote bitte.
Lies dir meine Aussage nochmal im direkten Kontext zum vorgestellten quote durch:
Quote
Quote
Durch dein split erzeugst du keine Hexzahlen sondern ASCII-Zeichen.


Genauer gesagt nul-terminierte Char-Arrays.

Wie kommst du in dieser Konstellation darauf, ich könnte über perl-Strings im Allgemeinen reden?

Ich habe gesagt, dass bei diesem split nul-terminierte Char-Arrays herauskommen. Was im Übrigen durchaus der Wahrheit entspricht.
But, don't believe me:
Code: (dl )
perldoc Devel::Peek|less -p'\\0'

Quote
The \0 at the end indicate that this PV is properly NUL-terminated.

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
perl -MDevel::Peek -e 'Dump [ split //, q{35312c38} ]'
SV = RV(0x817feb0) at 0x815399c
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x8153678
SV = PVAV(0x8157c64) at 0x8153678
REFCNT = 2
FLAGS = ()
IV = 0
NV = 0
ARRAY = 0x8175830
FILL = 7
MAX = 7
ARYLEN = 0x0
FLAGS = (REAL)
Elt No. 0
SV = PV(0x8153cb0) at 0x8152ce8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x816ea58 "3"\0
CUR = 1
LEN = 4
Elt No. 1
SV = PV(0x8153c74) at 0x8153660
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x816bd08 "5"\0
CUR = 1
LEN = 4
Elt No. 2
SV = PV(0x8153c8c) at 0x815366c
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x8174d50 "3"\0
CUR = 1
LEN = 4
Elt No. 3
SV = PV(0x8153d04) at 0x817d7dc
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x815b140 "1"\0
CUR = 1
LEN = 4

Und was sehen wir da? "3"\0, "5"\0, etc. Wow. Nach der Aussage aus perldoc würd ich fast vermuten, hier liegen nul-terminierte Char-Arrays im Speicher vor. Aber was weiß ich schon.
murphy
 2009-02-21 22:26
#119065 #119065
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
@FoolAck: Gerade in dem Kontext, in dem sie stand, machte Deine Aussage den Eindruck auf mich, dass Du behaupten wolltest, Perls Strings seien immer nullterminiert. Selbst wenn Du lediglich behaupten wolltest, Perls Strings seien in diesem speziellen Fall nullterminiert, finde ich die Aussage aber immer noch fragwuerdig.

Du hast zwar recht, dass Perl in der Regel hinter Strings ein Nullzeichen anfuegt, vermutlich um Bindings zu C-Bibliotheken das Leben leichter zu machen, ich wuerde aber trotzdem niemals sagen, dass Perls Strings nullterminiert sind, da das Ende des Strings nicht durch das Nullzeichen bestimmt wird. Das Suffix "terminiert" bedeutet fuer mich, dass das Ende durch das im Praefix naeher spezifizierte Objekt eindeutig bestimmt wird. Wenn am Ende eines Perlstrings oder im Speicher zufaellig dahinter ein "x" steht, kommt auch niemand auf die Idee zu behaupten, der String sei "x"-terminiert.

Dass die Perldokumentation ebenfalls den Ausdruck nullterminiert in diesem meiner Meinung nach inkorrekten, zumindest aber unpraezisen und stark irrefuehrenden, Sinn verwendet, war mir nicht bewusst.

Ich wollte also nur anmerken, dass Perl eben nicht genauso wie die Standard C-Bibliothek verfaehrt und das Ende von Strings durch die Anwesenheit eines Nullzeichens bestimmt, sondern die Laenge mit abspeichert, da ich das Gefuehl hatte, Dein Beitrag koennte bei jemandem ohne intime Kenntnisse der Perlinterna leicht einen falschen Eindruck erwecken.

Dass Du Dich offenbar durch meine Anmerkung gekraenkt fuehlst, tut mir leid.
When C++ is your hammer, every problem looks like your thumb.
<< |< 1 2 >| >> 12 Einträge, 2 Seiten



View all threads created 2009-02-16 14:19.