compressor.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2025-present The Bitcoin Core developers 3 # Distributed under the MIT software license, see the accompanying 4 # file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 """Routines for compressing transaction output amounts and scripts.""" 6 import unittest 7 8 from .messages import COIN 9 10 11 def compress_amount(n): 12 if n == 0: 13 return 0 14 e = 0 15 while ((n % 10) == 0) and (e < 9): 16 n //= 10 17 e += 1 18 if e < 9: 19 d = n % 10 20 assert (d >= 1 and d <= 9) 21 n //= 10 22 return 1 + (n*9 + d - 1)*10 + e 23 else: 24 return 1 + (n - 1)*10 + 9 25 26 27 def decompress_amount(x): 28 if x == 0: 29 return 0 30 x -= 1 31 e = x % 10 32 x //= 10 33 n = 0 34 if e < 9: 35 d = (x % 9) + 1 36 x //= 9 37 n = x * 10 + d 38 else: 39 n = x + 1 40 while e > 0: 41 n *= 10 42 e -= 1 43 return n 44 45 46 class TestFrameworkCompressor(unittest.TestCase): 47 def test_amount_compress_decompress(self): 48 def check_amount(amount, expected_compressed): 49 self.assertEqual(compress_amount(amount), expected_compressed) 50 self.assertEqual(decompress_amount(expected_compressed), amount) 51 52 # test cases from compress_tests.cpp:compress_amounts 53 check_amount(0, 0x0) 54 check_amount(1, 0x1) 55 check_amount(1000000, 0x7) 56 check_amount(COIN, 0x9) 57 check_amount(50*COIN, 0x32) 58 check_amount(21000000*COIN, 0x1406f40)