return stdout
+def byte_string(data, sep=' '):
+ r"""Convert a byte-string to human readable form
+
+ >>> byte_string(b'\x12\x34\x56')
+ '12 34 56'
+ """
+ return sep.join('{:02x}'.format(byte) for byte in data)
+
+
+def string_bytes(data, sep=' '):
+ r"""Reverse byte_string()
+
+ >>> string_bytes('12 fa fb')
+ b'\x12\xfa\xfb'
+ """
+ return bytes(
+ int(c1+c2, base=16) for c1,c2 in
+ zip(data[::2 + len(sep)], data[1::2 + len(sep)]))
+
+
class PGPPacket (dict):
# http://tools.ietf.org/search/rfc4880
_old_format_packet_length_type = { # type: (bytes, struct type)
if key in self:
value = self[key]
if isinstance(value, bytes):
- value = ' '.join('{:02x}'.format(byte) for byte in value)
+ value = byte_string(data=value)
lines.append(' {}: {}'.format(label, value))
return '\n'.join(lines)
subpacket['signature-creation-time'] = _struct.unpack('>I', data)[0]
def _parse_issuer_signature_subpacket(self, data, subpacket):
- subpacket['issuer'] = ''.join('{:02x}'.format(byte) for byte in data)
+ subpacket['issuer'] = byte_string(data=data, sep='')
def _parse_key_expiration_time_signature_subpacket(
self, data, subpacket):
raise ValueError(
('serialized {} differs from input packet: '
'at byte {}, {} != {}').format(
- self['type'], i,
- ' '.join('{:02x}'.format(byte) for byte in out_chunk),
- ' '.join('{:02x}'.format(byte) for byte in in_chunk)))
+ self['type'], i, byte_string(data=out_chunk),
+ byte_string(data=in_chunk)))
class PGPKey (object):