3

Consider:

$tag = "4F";

$tag is a string containing two characters, '4' and 'F'. I want to be able to treat these as the upper and lower nibbles respectively of a whole byte (4F) so that I can go on to compute the bit-patterns (01001111)

As these are technically characters, they can be treated in their own right as a byte each - 4 on the ASCII table is 0x52 and F is 0x70.

Pretty much all the PHP built-in functions that allow manipulation of bytes (that I've seen so far) are variations on the latter description: '4' is 0x52, and not the upper nibble of a byte.

I don't know of any quick or built-in way to get PHP to handle this the way I want, but it feels like it should be there.

How do I convert a string "4F" to the byte 4F, or treat each char as a nibble in a nibble-pair. Are there any built in functions to get PHP to handle a string like "4F" or "3F0E" as pairs of nibbles?

Thanks.

Andrew Weir
  • 41
  • 1
  • 6
  • 4
    [`hexdec`](http://php.net/manual/en/function.hexdec.php)? – bishop Nov 08 '18 at 15:14
  • @bishop Let's see if I got this right... Due to limited formatting options, the following snippet will do the hexdec() conversion, and then using sprintf, try to output a bitmask. `$tag = "4F"; $hexdec_result = hexdec($tag); $bitpattern = sprintf("%08x", $hexdec_result);` Produces the following output: Tag [ 4F ] expects bitpattern 01001111. hexdec() returns [ 79 ] bitpattern for this is [ 0000004f ] – Andrew Weir Nov 08 '18 at 15:22
  • @TLV Wouldn't it be `"%08b"` in the `sprintf` call if you want binary? Alternatively, just use `decbin` (or `base_convert` to wrap the whole thing up into one call). – iainn Nov 08 '18 at 15:24
  • @iainn Quite right you are, and that got me where I needed to go. Good man. – Andrew Weir Nov 08 '18 at 15:25
  • Another solution is to use `hexdec` with `str_pad` and `decbin`: `$tag = "4F"; $p = hexdec($tag); echo str_pad(decbin($p), 8, 0, STR_PAD_LEFT);`. Outputs `01001111` – AnTrakS Nov 08 '18 at 15:26
  • @D.Dimitrov Is there an advantage to using that method to sprintf? – Andrew Weir Nov 08 '18 at 15:26
  • Comparing your code with my suggestion there's a little difference in 3/3 tests with memory usage. All of the tests I've done with your code the memory usage is above 16700 kilobytes, mine all of them are below 16700. It's your matter what to use. Maybe in bigger projects there will be an advantage. – AnTrakS Nov 08 '18 at 15:30

1 Answers1

1

If you're wanting "the decimal representation of a hex digit", hexdec is one way to go.

If you're wanting "bit pattern for hex digit", then use base_convert. The docs even show an example of this maneuver:

Example #1 base_convert() example

$hexadecimal = 'a37334';
echo base_convert($hexadecimal, 16, 2);

The above example will output:

101000110111001100110100

bishop
  • 37,830
  • 11
  • 104
  • 139