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)
59