Re: Basic transformations
by kejohm (Hermit) on Nov 29, 2010 at 11:43 UTC
|
print pack 'c*', map {hex $_} qw(48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 2
+1);
produces:
Hello, world!
| [reply] [d/l] [select] |
|
|
The map function is what I was missing. That works perfectly. Thank you.
| [reply] |
Re: Basic transformations
by mjscott2702 (Pilgrim) on Nov 29, 2010 at 11:47 UTC
|
This seems to work, combining hex and chr - I'm sure it could be shorter:
use strict;
use warnings;
while(<DATA>) {
chomp;
my @hex_chars = split;
map { print chr(hex($_)); } @hex_chars;
print "\n";
}
__DATA__
48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21
Output:
Hello, world!
| [reply] [d/l] |
Re: Basic transformations
by chrestomanci (Priest) on Nov 29, 2010 at 11:43 UTC
|
use strict;
use warnings;
my $line = '48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21';
my @cbytes = split / /, $line;
my $retString;
foreach my $byte (@cbytes)
{
my $hex = '0x'.$byte;
my $value = eval $hex;
my $char = chr $value;
$retString .= $char;
}
print $retString;
The trick is that perl will evaluate a literal number as hex if you prefix it with '0x', you then need to use eval to force perl to re-evalute it as a number instead of a string. From there is is just a matter of using chr (see perlfunc) to turn that number into a 1 char string. | [reply] [d/l] [select] |
|
|
The trick is that perl will evaluate a literal number as hex if you prefix it with '0x', you then need to use eval to force perl to re-evalute it as a number instead of a string.
Any reason not use the build in hex function, and instead use an eval, which, if the data comes from an untrusted source, has potential to have some "unwanted"side effects?
| [reply] [d/l] [select] |
|
|
Only that I did not think to use hex. It would probably be a better approach than eval.
I don't think the OP had reason to distrust the input data, but if he did then it would be wise to sanitise with a regular expression like:my($clean) = ($raw =~ m/(\d+)/); regardless of how it is processed further.
| [reply] [d/l] [select] |
|
|
Re: Basic transformations
by jwkrahn (Abbot) on Nov 29, 2010 at 13:32 UTC
|
$ echo "48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21" | perl -lpe's/([[:xdig
+it:]]{2})\s*/ chr hex $1 /eg'
Hello, world!
| [reply] [d/l] |
Re: Basic transformations
by anonymized user 468275 (Curate) on Nov 29, 2010 at 16:51 UTC
|
Yet another one liner for this:
echo '48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21' | perl -lane 'for $ch (
+split /\s/ ) { $st .= chr(hex($ch)); } print $st;'
| [reply] [d/l] |
|
|
echo '48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21' | perl -lane '$st .= chr
+ hex for @F; print $st;'
| [reply] [d/l] [select] |
Re: Basic transformations
by locked_user sundialsvc4 (Abbot) on Nov 29, 2010 at 15:29 UTC
|
FYI, the pack/unpack functions can also sometimes be very useful.
| |
Re: Basic transformations
by Anonymous Monk on Nov 30, 2010 at 01:21 UTC
|
I am having another problem with this in practice. My code seems to work, but it is producing some error messages I don't understand.
A snippet of the actual code in use:
#!/usr/bin/perl -w
use strict;
open ( SOMEFILE, '<', "$ARGV[0]" )
or die "Can't open $ARGV[0] for reading.\n";
while (defined($_ = <SOMEFILE>))
{
my @cbytes = split;
my @hbytes = map(hex, @cbytes);
my $hstring = pack('c*', @hbytes);
}
close SOMEFILE;
One line of data (remember, I only used printable characters for the example):
99 00 00 00 dd 02
And the output:
Character in 'c' format wrapped in pack at ./test.pl line 11, <SOMEFIL
+E> line 1.
Character in 'c' format wrapped in pack at ./test.pl line 11, <SOMEFIL
+E> line 1.
Can someone tell me what is going on here? Thanks. | [reply] [d/l] [select] |
|
|
| [reply] |
|
|
$s = '48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21';;
$s =~ tr[ ][]d;
print pack 'H*', $s;;
Hello, world!
| [reply] [d/l] |
|
|
Thanks. I don't know how I missed that.
| [reply] |
|
|
Re: Basic transformations
by fisher (Priest) on Nov 29, 2010 at 11:45 UTC
|
for your example it is enough to just do
while (<SOMEFILE>) {
@bytes = split //;
print join ":", @bytes;
}
| [reply] [d/l] |
|
|
Please try your suggestion with an example. It's very wrong.
| [reply] |