What does the "B"
do in this pack
statement from Perl code?
$hce_hash=pack('B*', $hce_hash);
Is there an equivalent function in PHP?
PHP’s pack
doesn’t support a format of B*
, but it does support H*
. In Perl, you could emulate it with
sub pack_Bstar {
my($bits) = @_;
my $Hstar;
my $nybble = 0;
for (my $i = 0; $i < length $bits; ++$i) {
$nybble *= 2;
$nybble += int substr($bits, $i, 1);
if ($i % 4 == 3) {
$Hstar .= sprintf "%x", $nybble;
$nybble = 0;
}
}
my $pad = 4 - length($bits) % 4;
if ($pad != 4) {
$nybble = ($nybble << $pad);
$Hstar .= sprintf "%x", $nybble;
}
pack "H*", $Hstar;
}
The code above is not idiomatic Perl, but translation to PHP should be straightforward.
The H*
format wants a hex string with high nybble (4 bits) first. The code above chews off four bits at a time to compute each nybble value. For example, for a bit string of 1011
, tracing the algorithm gives
10112 is indeed 1110, which is b16. If the last nybble is incomplete (between one and three bits), we left-shift the bit the appropriate number of places. This has the effect of zero-padding on the right.
Tests:
my @tests = (
["01001010011101010111001101110100" => "Just"],
["0110000101101110011011110111010001101000011001010111001" => "another"],
["01010000010010000101000000101111010100000110010101110010011011" => "PHP/Perl"],
["01101000011000010110001101101011011001010111001000101100" => "hacker,"],
);
for (@tests) {
my($input,$expect) = @$_;
my $got = pack_Bstar $input;
print "$input: ", ($got eq $expect ? "PASS" : "FAIL"), " ($got)\n";
}
Output:
01001010011101010111001101110100: PASS (Just) 0110000101101110011011110111010001101000011001010111001: PASS (another) 01010000010010000101000000101111010100000110010101110010011011: PASS (PHP/Perl) 01101000011000010110001101101011011001010111001000101100: PASS (hacker,)