46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
import re
|
|
import os.path
|
|
import hashlib
|
|
|
|
from collections import namedtuple
|
|
|
|
|
|
Digest = namedtuple('Digest', ['is_tarsum', 'tarsum_version', 'hash_alg', 'hash_bytes'])
|
|
|
|
|
|
DIGEST_PATTERN = r'(tarsum\.(v[\w]+)\+)?([\w]+):([0-9a-f]+)'
|
|
DIGEST_REGEX = re.compile(DIGEST_PATTERN)
|
|
|
|
|
|
class InvalidDigestException(RuntimeError):
|
|
pass
|
|
|
|
|
|
def parse_digest(digest):
|
|
""" Returns the digest parsed out to its components. """
|
|
match = DIGEST_REGEX.match(digest)
|
|
if match is None or match.end() != len(digest):
|
|
raise InvalidDigestException('Not a valid digest: %s', digest)
|
|
|
|
is_tarsum = match.group(1) is not None
|
|
return Digest(is_tarsum, match.group(2), match.group(3), match.group(4))
|
|
|
|
|
|
def content_path(digest):
|
|
""" Returns a relative path to the parsed digest. """
|
|
parsed = parse_digest(digest)
|
|
components = []
|
|
|
|
if parsed.is_tarsum:
|
|
components.extend(['tarsum', parsed.tarsum_version])
|
|
|
|
prefix = parsed.hash_bytes[0:2].zfill(2)
|
|
components.extend([parsed.hash_alg, prefix, parsed.hash_bytes])
|
|
|
|
return os.path.join(*components)
|
|
|
|
|
|
def sha256_digest(content):
|
|
""" Returns a sha256 hash of the content bytes in digest form. """
|
|
digest = hashlib.sha256(content)
|
|
return 'sha256:{0}'.format(digest.hexdigest())
|