On Mon, Mar 31, 2014 at 6:29 PM, Alan DeKok <aland@deployingradius.com> wrote:
  Yes.  The parser is forgiving.  If you give a hex string to an
attribute of "octets" type, it parses the hex into binary data.  If you
give a printable string to an "octets" attribute, it assumes you're
being lazy.  The printable string is used as the value for the attribute.


OK.  So it's the "forgivingness" that gives the appearance of inconsistency here because of that extra conversion. 
 
  No.  The binary attributes are printed and parsed as hex strings:
0xabcdef.  That is the normal (and expected) method of operation.

Knowing that now makes a big difference, so yes, treating them as "0x"-prepended hex strings at both ends does give me consistent behaviour.  Things seem to work in the general case with something like:

$RAD_REPLY{'State'} = "0x".unpack("H*",$data);
and
my $data = pack("H*",substr($RAD_REPLY{'State'},2)); # remove leading '0x' before pack

to move data in and out of the attribute.