in reply to Re^3: Split any number into string of 8-bit hex values (=1 byte) in thread Split any number into string of 8-bit hex values (=1 byte)
Yes please :-) If I'd convert anything from a quad and then remove unnecessary leading zeros so that I'd end up with 1, 2, 4 or 8 bytes I'm thinking that this should work. What does the regex look like?
Re^5: Split any number into string of 8-bit hex values (=1 byte)
by tybalt89 (Monsignor) on Aug 30, 2021 at 19:54 UTC
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11136191
use warnings;
for my $n (0, 2, 20, 200, 2000, 20000, 200000)
{
my @bytes = reverse sprintf('%016X', $n) =~ s/^0{8}(0{4}(00)?)?//r =
+~ /../g;
print "$n => @bytes\n";
}
Outputs:
0 => 00
2 => 02
20 => 14
200 => C8
2000 => D0 07
20000 => 20 4E
200000 => 40 0D 03 00
| [reply] [d/l] [select] |
|
Well.... I'm not sure how your regex works BUT it works great for unsigned numbers :-)
#!/usr/bin/perl
use strict;
use warnings;
sub number2hexString {
return my $output .= join ' ', map { join ' ', sprintf('%016X'
+, $_) =~ s/^0{8}(0{4}(00)?)?//r =~ /../g } @_;
}
print number2hexString(2,20,200,2000,20000,200000)."\n";
It doesn't completely solve my problem as it does not work with unsigned signed numbers
UPDATE: sorry, I was confused, obviously the last sentence should read ... does not work with signed numbers | [reply] [d/l] |
|
Further to tybalt89's comment:
... your regex works ... works great for unsigned numbers ...
[…]
... it does not work with unsigned numbers ...
I assume you mean signed numbers in the second case; if so, please supply representative test cases: just what output do you expect for -255, -256, -65535, -65536, etc.
And I would strongly suggest concentrating on edge cases in your test cases, e.g. something like
0, 1, 255, 256, 65535, 65536, 16777215, 16777216, 4294967295
rather than
2 20 200 2000 20000 200000
Update: Also, are you aware that the sprintf 'x' format conversion is essentially unsigned:
Win8 Strawberry 5.8.9.5 (32) Mon 08/30/2021 18:24:36
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
printf "%08x \n", -256;
printf "%08x \n", 4294967040;
^Z
ffffff00
ffffff00
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
Win8 Strawberry 5.30.3.1 (64) Mon 08/30/2021 18:36:38
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
my @n_list = (0, 1, 255, 256, 65535, 65536, 16777215, 16777216, 429496
+7295,);
sub n2hstr_2 { # compatible with perl version 5.8
return
join ' ',
map {
my $w = $_ > 65535 ? 8 : $_ > 255 ? 4 : 2;
unpack '(a2)*', sprintf '%0*x', $w, $_;
}
@_
;
}
sub number2hexString {
my $output;
my $packTemplate;
foreach my $i (@_) {
if ($i > 65535) {
$packTemplate = 'L>';
} elsif ($i > 255) {
$packTemplate = 'S>';
} else {
$packTemplate = 'C';
}
$output .= join(' ', unpack('(H2)*', pack($packTemplat
+e, $i))).' ';
}
return $output;
}
my $n_n2hstr = n2hstr_2 (@n_list);
my $n_number2hexString = number2hexString(@n_list);
print "@n_list \n";
print "'$n_n2hstr' \n";
print "'$n_number2hexString' \n";
^Z
0 1 255 256 65535 65536 16777215 16777216 4294967295
'00 01 ff 01 00 ff ff 00 01 00 00 00 ff ff ff 01 00 00 00 ff ff ff ff'
'00 01 ff 01 00 ff ff 00 01 00 00 00 ff ff ff 01 00 00 00 ff ff ff ff
+'
As you see, the outputs are the same — except that number2hexString() adds an extra space at the end of the output string!
I don't attempt to handle negative numbers since I don't yet understand how
they should be handled.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
|
|
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11136191
use warnings;
my @test = map 2 * 10 ** $_, 0 .. 16;
for my $n ( 0, @test, map -$_, @test )
{
my @bytes = reverse sprintf('%016X', $n) =~
s/^0{8}(0{4}(00)?)?(?=[0-7])//r =~
s/^F{8}(F{4}(FF)?)?(?=[89A-F])//r =~
/../g;
print "$n => @bytes\n";
}
Outputs:
0 => 00
2 => 02
20 => 14
200 => C8 00
2000 => D0 07
20000 => 20 4E
200000 => 40 0D 03 00
2000000 => 80 84 1E 00
20000000 => 00 2D 31 01
200000000 => 00 C2 EB 0B
2000000000 => 00 94 35 77
20000000000 => 00 C8 17 A8 04 00 00 00
200000000000 => 00 D0 ED 90 2E 00 00 00
2000000000000 => 00 20 4A A9 D1 01 00 00
20000000000000 => 00 40 E5 9C 30 12 00 00
200000000000000 => 00 80 F4 20 E6 B5 00 00
2000000000000000 => 00 00 8D 49 FD 1A 07 00
20000000000000000 => 00 00 82 DF E4 0D 47 00
-2 => FE
-20 => EC
-200 => 38 FF
-2000 => 30 F8
-20000 => E0 B1
-200000 => C0 F2 FC FF
-2000000 => 80 7B E1 FF
-20000000 => 00 D3 CE FE
-200000000 => 00 3E 14 F4
-2000000000 => 00 6C CA 88
-20000000000 => 00 38 E8 57 FB FF FF FF
-200000000000 => 00 30 12 6F D1 FF FF FF
-2000000000000 => 00 E0 B5 56 2E FE FF FF
-20000000000000 => 00 C0 1A 63 CF ED FF FF
-200000000000000 => 00 80 0B DF 19 4A FF FF
-2000000000000000 => 00 00 73 B6 02 E5 F8 FF
-20000000000000000 => 00 00 7E 20 1B F2 B8 FF
Note that for 200, C8 is a negative number, so the 00 is required to make it so that C8 00 is positive.
| [reply] [d/l] [select] |
|
|
|
| [reply] |
|
|