|
5 | 5 | import re |
6 | 6 | import time |
7 | 7 | import uuid |
| 8 | +import zlib |
8 | 9 | from enum import Enum |
9 | 10 | from pathlib import Path |
10 | 11 | from typing import Optional |
|
13 | 14 | import boto3 |
14 | 15 | import pytest |
15 | 16 | from _pytest.fixtures import FixtureRequest |
| 17 | +from awscrt import checksums as awscrt_checksums |
16 | 18 | from boto3.s3.transfer import TransferConfig |
17 | 19 | from botocore.client import Config |
18 | 20 | from botocore.exceptions import ClientError |
@@ -416,3 +418,51 @@ def checksum_algorithms() -> list[ChecksumAlgorithm]: |
416 | 418 | ChecksumAlgorithm.CRC32C, |
417 | 419 | ChecksumAlgorithm.CRC64NVME, |
418 | 420 | ] |
| 421 | + |
| 422 | +def crc32(data: bytes) -> bytes: |
| 423 | + crc = zlib.crc32(data) & 0xFFFFFFFF |
| 424 | + return crc.to_bytes(4, byteorder="big") |
| 425 | + |
| 426 | +def crc32_b64(data: bytes) -> str: |
| 427 | + return base64.b64encode(crc32(data)).decode("ascii") |
| 428 | + |
| 429 | +def crc64nvme(data: bytes) -> bytes: |
| 430 | + checksum = awscrt_checksums.crc64nvme(data) |
| 431 | + return checksum.to_bytes(8, byteorder="big") |
| 432 | + |
| 433 | +def crc64nvme_b64(data: bytes) -> str: |
| 434 | + return base64.b64encode(crc64nvme(data)).decode("ascii") |
| 435 | + |
| 436 | +def hex_digest(path: str) -> str: |
| 437 | + h = hashlib.sha256() |
| 438 | + with open(path, "rb") as f: |
| 439 | + while True: |
| 440 | + chunk = f.read(8192) |
| 441 | + if not chunk: |
| 442 | + break |
| 443 | + h.update(chunk) |
| 444 | + return h.hexdigest() |
| 445 | + |
| 446 | + |
| 447 | +def multipart_etag_hex(parts: list[bytes]) -> str: |
| 448 | + digests = [hashlib.md5(part).digest() for part in parts] |
| 449 | + combined = hashlib.md5(b"".join(digests)).hexdigest() |
| 450 | + return f"{combined}-{len(parts)}" |
| 451 | + |
| 452 | + |
| 453 | +def multipart_crc32_checksum(parts: list[bytes]) -> str: |
| 454 | + part_checksums = [ |
| 455 | + crc32(part) |
| 456 | + for part in parts |
| 457 | + ] |
| 458 | + checksum_b64 = crc32_b64(b"".join(part_checksums)) |
| 459 | + return f"{checksum_b64}-{len(parts)}" |
| 460 | + |
| 461 | + |
| 462 | +def multipart_crc64nvme_checksum(parts: list[bytes]) -> str: |
| 463 | + part_checksums = [ |
| 464 | + crc64nvme(part) |
| 465 | + for part in parts |
| 466 | + ] |
| 467 | + checksum_b64 = crc64nvme_b64(b"".join(part_checksums)) |
| 468 | + return f"{checksum_b64}-{len(parts)}" |
0 commit comments