Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Unpack and checksums

Reply
Thread Tools

Unpack and checksums

 
 
Fatted
Guest
Posts: n/a
 
      05-26-2004
I'm trying to get unpack to generate a checksum but the result is always 0.
E.G.

my $string = 'ThisIsAString';

my $chksum = unpack("%H*",$string);

print $chksum."\n";


Results in 0.

perlfunc says unpack will generate the checksum (default 16 bit) if the
template is preceded by %.
What am I missing?
 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      05-26-2004
Fatted <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> I'm trying to get unpack to generate a checksum but the result is always 0.
> E.G.
>
> my $string = 'ThisIsAString';
>
> my $chksum = unpack("%H*",$string);
>
> print $chksum."\n";
>
>
> Results in 0.
>
> perlfunc says unpack will generate the checksum (default 16 bit) if the
> template is preceded by %.
> What am I missing?


There seems to be a bug in unpack, which appears to return a spurious
0 with the "%H" format. Try

perl -le 'print join( " | ", unpack "%H*", "a")'

to see it. As a workaround, use

my ( $chksum) = unpack("%H*",$string);

Anno
 
Reply With Quote
 
 
 
 
fifo
Guest
Posts: n/a
 
      05-26-2004
At 2004-05-26 10:29 +0000, Anno Siegel wrote:
> There seems to be a bug in unpack, which appears to return a spurious
> 0 with the "%H" format. Try
>
> perl -le 'print join( " | ", unpack "%H*", "a")'
>
> to see it. As a workaround, use
>
> my ( $chksum) = unpack("%H*",$string);
>


Isn't this just the same as doing

my $chksum = unpack("H*",$string);

as unpack "H*" is only going to give you a single scalar anyway?
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      05-26-2004
fifo <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> At 2004-05-26 10:29 +0000, Anno Siegel wrote:
> > There seems to be a bug in unpack, which appears to return a spurious
> > 0 with the "%H" format. Try
> >
> > perl -le 'print join( " | ", unpack "%H*", "a")'
> >
> > to see it. As a workaround, use
> >
> > my ( $chksum) = unpack("%H*",$string);
> >

>
> Isn't this just the same as doing
>
> my $chksum = unpack("H*",$string);
>
> as unpack "H*" is only going to give you a single scalar anyway?


We're not talking "H*" but "%H*". There's a *bug*, and it doesn't
behave according to specification.

Please read for comprehension.

Anno
 
Reply With Quote
 
Fatted
Guest
Posts: n/a
 
      05-26-2004
Anno Siegel wrote:

> fifo <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>
>>Isn't this just the same as doing
>>
>> my $chksum = unpack("H*",$string);
>>
>>as unpack "H*" is only going to give you a single scalar anyway?

>
>
> We're not talking "H*" but "%H*". There's a *bug*, and it doesn't
> behave according to specification.
>
> Please read for comprehension.
>
> Anno


I don't think I follow either

take:

my $string = 'ThisIsAString';
# PERFORM PLAIN UNPACK
my $chksum = unpack("H*",$string)."\n";
print $chksum."\n";

gives:
54686973497341537472696e67

try:

my $string = 'ThisIsAString';
# PERFORM CHECKSUM UNPACK
my $chksum = unpack("%H*",$string);
print $chksum."\n";

gives:
0
as discussed

try suggested workaround:

my $string = 'ThisIsAString';
# PERFORM WORKAROUND CHECKSUM UNPACK
my ($chksum) = unpack("%H*",$string);
print $chksum."\n";

gives:
54686973497341537472696e67
which is the same result as the plain unpack and not the checksum sought.








 
Reply With Quote
 
fifo
Guest
Posts: n/a
 
      05-26-2004
At 2004-05-26 11:12 +0000, Anno Siegel wrote:
> fifo <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > At 2004-05-26 10:29 +0000, Anno Siegel wrote:
> > > There seems to be a bug in unpack, which appears to return a spurious
> > > 0 with the "%H" format. Try
> > >
> > > perl -le 'print join( " | ", unpack "%H*", "a")'
> > >
> > > to see it. As a workaround, use
> > >
> > > my ( $chksum) = unpack("%H*",$string);
> > >

> >
> > Isn't this just the same as doing
> >
> > my $chksum = unpack("H*",$string);
> >
> > as unpack "H*" is only going to give you a single scalar anyway?

>
> We're not talking "H*" but "%H*". There's a *bug*, and it doesn't
> behave according to specification.
>
> Please read for comprehension.


I agree that there's a bug with "%H*". The point I was trying to make
was that "%H*" doesn't do anything useful over "H*" anyway, since it's
just 'summing' a single value. I was thinking maybe the OP really meant
to use "%C*"?
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      05-26-2004
Fatted <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
>
> > fifo <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> >
> >>Isn't this just the same as doing
> >>
> >> my $chksum = unpack("H*",$string);
> >>
> >>as unpack "H*" is only going to give you a single scalar anyway?

> >
> >
> > We're not talking "H*" but "%H*". There's a *bug*, and it doesn't
> > behave according to specification.
> >
> > Please read for comprehension.
> >
> > Anno

>
> I don't think I follow either
>
> take:
>
> my $string = 'ThisIsAString';
> # PERFORM PLAIN UNPACK
> my $chksum = unpack("H*",$string)."\n";
> print $chksum."\n";
>
> gives:
> 54686973497341537472696e67
>
> try:
>
> my $string = 'ThisIsAString';
> # PERFORM CHECKSUM UNPACK
> my $chksum = unpack("%H*",$string);
> print $chksum."\n";
>
> gives:
> 0
> as discussed
>
> try suggested workaround:
>
> my $string = 'ThisIsAString';
> # PERFORM WORKAROUND CHECKSUM UNPACK
> my ($chksum) = unpack("%H*",$string);
> print $chksum."\n";
>
> gives:
> 54686973497341537472696e67
> which is the same result as the plain unpack and not the checksum sought.


Ugh, you're right. I didn't notice it doesn't do the checksum at all.
Forget the workaround, sorry.

Anno
 
Reply With Quote
 
Fatted
Guest
Posts: n/a
 
      05-26-2004
fifo wrote:

> I agree that there's a bug with "%H*". The point I was trying to make
> was that "%H*" doesn't do anything useful over "H*" anyway, since it's
> just 'summing' a single value. I was thinking maybe the OP really meant
> to use "%C*"?


What I was looking for was the unpack equivalent of:
####
my $string = 'ThisIsAString';
my $chksum = 0;

for( split(//,$string) )
{
$chksum += ord;
}

print sprintf("%X",$chksum)."\n";
####

I thought "%H*" would handle that (if "H*" gives a concat of the hex
values then "%H*" should give sum, right?), but then comparing "H*" with
"C*":

"H*" returns the concatentation of the hex values of the string
whereas
"C*" returns the decimal value of the first value.

On the other hand "%C*" *does* return the checksum (in decimal).

I've read and reread the perlfunc for pack and unpack and I'm now pretty
confused.
 
Reply With Quote
 
fifo
Guest
Posts: n/a
 
      05-26-2004
At 2004-05-26 15:41 +0200, Fatted wrote:
> What I was looking for was the unpack equivalent of:
> ####
> my $string = 'ThisIsAString';
> my $chksum = 0;
>
> for( split(//,$string) )
> {
> $chksum += ord;
> }
>
> print sprintf("%X",$chksum)."\n";
> ####
>
> I thought "%H*" would handle that (if "H*" gives a concat of the hex
> values then "%H*" should give sum, right?), but then comparing "H*" with
> "C*":
>
> "H*" returns the concatentation of the hex values of the string
> whereas


It returns a single string of hexadecimal digits.

> "C*" returns the decimal value of the first value.


No it returns a _list_ of the char values of each byte in the string:

$ perl -le'print join ":", unpack "C*", "ThisIsAString"'
84:104:105:115:73:115:65:83:116:114:105:110:103
 
Reply With Quote
 
Greg Bacon
Guest
Posts: n/a
 
      05-26-2004
In article <(E-Mail Removed)>,
Fatted <(E-Mail Removed)> wrote:

: What I was looking for was the unpack equivalent of:
: ####
: my $string = 'ThisIsAString';
: my $chksum = 0;
:
: for( split(//,$string) )
: {
: $chksum += ord;
: }
:
: print sprintf("%X",$chksum)."\n";
: ####

You're right there! Well, sort of. See below.

$ cat try
#!/usr/local/bin/perl -w

use strict;
use warnings;

sub explicit_checksum {
my $str = shift;

my $sum = 0;
$sum += ord for split // => $str;

$sum;
}

sub unpack_checksum {
unpack "%16C*", shift;
}

my $string = 'ThisIsAString';
my $chksum = 0;

for (split //, $string) {
$chksum += ord;
}

my @method = (
[ explicit => \&explicit_checksum ],
[ unpack => \&unpack_checksum ],
);

for (@method) {
my($name,$code) = @$_;

printf "%-10s %X\n", $name . ":", $code->($string);
}

$ ./try
explicit: 50C
unpack: 50C

These results match coincidentally. Given a long enough $string, i.e.,
one whose ASCII values sum greater than 0xFFFF, only the least
significant sixteen bits would match.

For example:

$ cat try
[...]
open my $fh, '/etc/lynx.cfg' or die "$0: open /etc/lynx.cfg: $!";
my $string = join '', <$fh>;
[...]

$ ./try
explicit: ADA3B4
unpack: A3B4

The unpack isn't equivalent, but that's because the checksum your code
computes doesn't follow the convention of producing a result clamped
to a certain number of bits, e.g., $sum & 0xFFFF for a 16-bit checksum.

: I thought "%H*" would handle that (if "H*" gives a concat of the hex
: values then "%H*" should give sum, right?), but then comparing "H*"
: with "C*":

Remember that H returns hex strings, but C returns unsigned char
values. Which of these matches the values returned from Perl's ord
operator?

: On the other hand "%C*" *does* return the checksum (in decimal).

No, it doesn't return a value in a particular base, just a number.
Base is a representation, e.g., input and output, issue. Yes, I
realize it's almost certainly a twos-complement bitpattern in some
register in your machine, but we're speaking at the level of
abstraction of the Perl programming language, not the bare metal.

: I've read and reread the perlfunc for pack and unpack and I'm now
: pretty confused.

I hope this helps you through the confusion.

Greg
--
'Necessity' is the plea for every infringement of human liberty. It is
the argument of tyrants; it is the creed of slaves.
-- William Pitt
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Calculating md5 checksums. Fredrik Lundh Python 1 03-04-2006 12:41 AM
Bit IO, digests, checksums Igor Planinc Java 15 11-18-2005 10:01 PM
How good are checksums? Chris Java 12 04-30-2004 07:48 PM
class checksums Michael Fairbank Java 16 12-12-2003 01:25 PM
Files and Checksums Rob Javascript 0 08-27-2003 05:52 PM



Advertisments