xref: /aosp_15_r20/external/cronet/third_party/icu/scripts/icuhash.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/python3
2*6777b538SAndroid Build Coastguard Worker
3*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors. All rights reserved.
4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Workerimport hashlib
8*6777b538SAndroid Build Coastguard Workerimport itertools
9*6777b538SAndroid Build Coastguard Workerimport sys
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard WorkerPAGE_SIZE = 0x1000  # System page size.
12*6777b538SAndroid Build Coastguard WorkerHASH_SIZE = 8       # Size of the hash in bytes.
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Workerdef hash_pages(data):
16*6777b538SAndroid Build Coastguard Worker    out = bytearray()
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker    offset = 0
19*6777b538SAndroid Build Coastguard Worker    while offset < len(data):
20*6777b538SAndroid Build Coastguard Worker        # Extract a page and pad it with zeroes in case it's not a full page.
21*6777b538SAndroid Build Coastguard Worker        # This is to emulate the behavior of mmap in Linux (and thus ChromeOS)
22*6777b538SAndroid Build Coastguard Worker        # environments.
23*6777b538SAndroid Build Coastguard Worker        #
24*6777b538SAndroid Build Coastguard Worker        #     "POSIX specifies that the system shall always zero fill any
25*6777b538SAndroid Build Coastguard Worker        #      partial page at the end of the object [...]".
26*6777b538SAndroid Build Coastguard Worker        #
27*6777b538SAndroid Build Coastguard Worker        # Reference: https://man7.org/linux/man-pages/man2/mmap.2.html
28*6777b538SAndroid Build Coastguard Worker        page = bytearray(data[offset : offset + PAGE_SIZE])
29*6777b538SAndroid Build Coastguard Worker        page.extend(itertools.repeat(0x00, PAGE_SIZE - len(page)))
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker        # Calculate the hash of the page.
32*6777b538SAndroid Build Coastguard Worker        digest = hashlib.blake2b(page, digest_size=HASH_SIZE).digest()
33*6777b538SAndroid Build Coastguard Worker        out.extend(digest)
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker        offset += PAGE_SIZE
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker    return out
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Workerif __name__ == "__main__":
41*6777b538SAndroid Build Coastguard Worker    # Check arguments.
42*6777b538SAndroid Build Coastguard Worker    if len(sys.argv) != 3:
43*6777b538SAndroid Build Coastguard Worker        error_str = "icuhash: wrong number of arguments\n\n"
44*6777b538SAndroid Build Coastguard Worker        help_str = "usage: icuhash <infilename> <outfilename>\n\n"
45*6777b538SAndroid Build Coastguard Worker        sys.exit(error_str + help_str)
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker    # Extract arguments.
48*6777b538SAndroid Build Coastguard Worker    in_filename = sys.argv[1]
49*6777b538SAndroid Build Coastguard Worker    out_filename = sys.argv[2]
50*6777b538SAndroid Build Coastguard Worker
51*6777b538SAndroid Build Coastguard Worker    # Read the input file.
52*6777b538SAndroid Build Coastguard Worker    with open(in_filename, "rb") as in_file:
53*6777b538SAndroid Build Coastguard Worker        data = in_file.read()
54*6777b538SAndroid Build Coastguard Worker        # Calculate hashes for each page of the file.
55*6777b538SAndroid Build Coastguard Worker        out_data = hash_pages(data)
56*6777b538SAndroid Build Coastguard Worker        # Write the output file.
57*6777b538SAndroid Build Coastguard Worker        with open(out_filename, "wb") as out_file:
58*6777b538SAndroid Build Coastguard Worker            out_file.write(out_data)
59