cstrong has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm trying to send an octal string to a receiving host.  The code example below shows the original ASCII values (in hex) of the command.  My script then loops over each two byte pair and converts the ASCII (hex values) to octal ready for sending to the host (and I agree that part is probably a bit long-winded).

Anyway, the problem is that if I try to send a simple string of octal digits (see $goodoct) it works fine, however the string returned from the sub convert is a literal string of characters and not interpreted as actual octal values.  I can tell this to be the case even without looking at the host side as the printed output (in Windows) for $octcommand shows "\2\61\70" etc whereas the output for $goodoct shows actual ASCII chars.

Its obviously a simple mistake somewhere on my part, but I'm having trouble seeing what the difference between the variable contents of $goodoct and $octcommd are.  All help appreciated!
#!/usr/bin/perl # $hexcommand="02313832300030010000c000003030353130303038313032343034343 +83236383331343135353430303030303030303030343135353430303003"; convert($hexcommand); print "DERRIVED OCTAL\n$octcommand\n\n"; $goodoct="\2\61\70\62\60\0\60\1\0\0\300\0\0\60\60\65\61\60\60\60\70\61 +\60\62\64\60\64\64\70\62\66\70\63\61\65\65\64\60\60\60\60\60\60\60\60 +\60\60\64\61\65\65\64\60\60\60\3"; print "GOOD OCTAL\n$goodoct\n\n"; sub convert { $hexcommand=shift; $length = length($hexcommand); $tot = ($length/2)-1; print "length is: $length\n"; print "tot is: $tot\n"; for ($x=0; $x<=$tot; $x++){ $chunk = substr($hexcommand, $offset, 2); $dec = &hex2dec($chunk); $octbyte=sprintf "%lo", $dec; $octcommand = $octcommand . "\\" . $octbyte; $offset+=2; } return $octcommand; } sub hex2dec($) { return hex $_[0] }

Replies are listed 'Best First'.
Re: Returning variable from sub
by afresh1 (Hermit) on Oct 28, 2008 at 16:08 UTC

    If you read packing hex you can find the answer there. What it boils down to is replacing convert($hexcommand) with pack ( "H*", $hexcommand ). That would make your script:

    #!/usr/bin/perl use strict; use warnings; my $hexcommand="02313832300030010000c000003030353130303038313032343034 +34383236383331343135353430303030303030303030343135353430303003"; my $octcommand = pack ( "H*", $hexcommand ); print "DERRIVED OCTAL: $octcommand\n"; my $goodoct="\2\61\70\62\60\0\60\1\0\0\300\0\0\60\60\65\61\60\60\60\70 +\61\60\62\64\60\64\64\70\62\66\70\63\61\65\65\64\60\60\60\60\60\60\60 +\60\60\60\64\61\65\65\64\60\60\60\3"; print " GOOD OCTAL: $goodoct\n";

    Although it appears that you are missing something in $goodoct because my result is:

    DERRIVED OCTAL: 18200&#65533;00510008102404482683141554000000000041554 +000 GOOD OCTAL: 18200&#65533;00510008102404482683155400000000004155400 +0
    l8rZ,
    --
    andrew
Re: Returning variable from sub
by smiffy (Pilgrim) on Oct 29, 2008 at 05:40 UTC

    One tiny point - the correct English spelling of derived is <---. Unless you mean something else, of course.

    You might also want to think about:

    use strict; use warnings;

    If I don't say it, someone else is bound to ;-) See docs for strict and warnings.

Re: Returning variable from sub
by wol (Hermit) on Oct 29, 2008 at 14:57 UTC
    The convention of using a backslash and digits to get octal values into a string is only needed for string literals.

    In your case, you know the value of the byte you want in the string ($dec), so you can add it to the string with:

    $octcommand = $octcommand . chr $dec;
    That explains why your code isn't doing what you expect. However, don't just do that: I second afresh1's suggestion of using pack. No need to implement pack when it's already part of the language :-)

    --
    .sig : File not found.