Source code for bioutils.digest

import base64
import binascii

_enc = "ascii"

[docs]class Digest(bytes): """Represents a sliceable binary digest, with support for encoding and decoding using printable characters. Supported encoding and decodings are:: * base64 * base64url * hex (aka base16) The Base64 specification ( defines base64 and a URL-safe variant called base64url. "Stringified" Digest objects use URL-safe base64 encodings. >>> import hashlib >>> b = hashlib.sha512().digest() >>> len(b) 64 >>> d = Digest(b) # creation >>> str(d) # returns base64url 'z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg_SpIdNs6c5H0NE8XYXysP-DGNKHfuwvY7kxvUdBeoGlODJ6-SfaPg==' >>> d24 = d[:24] # slice binary digest at first 24 bytes >>> str(d24) 'z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXc' # encoding >>> d.as_base64url() 'z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg_SpIdNs6c5H0NE8XYXysP-DGNKHfuwvY7kxvUdBeoGlODJ6-SfaPg==' >>> d.as_hex() 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e' # decoding >>> d == Digest.from_base64(d.as_base64()) True >>> d == Digest.from_base64url(d.as_base64url()) True >>> d == Digest.from_hex(d.as_hex()) True """ def __str__(self): """returns digest as base64url string""" return self.as_base64url() # TODO: Consider requiring slice start == None or 0, and len % 3 == 0 # Slicing %3 != 0 => strings will having suffix differences def __getitem__(self, key): return Digest(bytes.__getitem__(self, key)) # base64
[docs] def as_base64(self): """Returns Digest as a base64-encoded string. Returns: str: base64 encoding of Digest. """ return base64.b64encode(self).decode(_enc)
[docs] @staticmethod def from_base64(s): """Returns Digest object initialized from a base64-encoded string. Args: s (str): A base64-encoded digest string. Returns: Digest: A Digest object initialized from s. """ return Digest(base64.b64decode(s))
# base64url
[docs] def as_base64url(self): """Returns Digest as URL-safe, base64-encoded string. Returns: str: URL-safe base64 encoding of Digest. """ return base64.urlsafe_b64encode(self).decode(_enc)
[docs] @staticmethod def from_base64url(s): """Returns Digest object initialized from a base64url string. Args: s (str): A base64url-encoded digest string. Returns: Digest: A Digest object initialized from s. """ return Digest(base64.urlsafe_b64decode(s))
# for backward compatibility with earlier versions # ("base64url" is the official name for the encoding) as_base64us = as_base64url from_base64us = from_base64url # hex
[docs] def as_hex(self): """Returns Digest as hex string. Returns: str: A hex-encoding of Digest. """ return binascii.hexlify(self).decode(_enc)
[docs] @staticmethod def from_hex(s): """returns Digest object initialized from hex string. Args: s (str): A hex-encoded digest string. Returns: Digest: A Digest object initialized from s. """ return Digest(binascii.unhexlify(s))
if __name__ == "__main__": # pragma: nocover import hashlib b = hashlib.sha512().digest() d = Digest(b) assert isinstance(d, Digest), "d isn't a Digest" d24 = d[:24] assert isinstance(d24, Digest), "d24 isn't a Digest" e = Digest.from_base64url(d.as_base64url()) e24 = Digest.from_base64url(d24.as_base64url())