source: trunk/src/allmydata/test/test_base62.py

Last change on this file was 168532d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-12-21T18:03:57Z

finish removing "future"

  • Property mode set to 100644
File size: 3.4 KB
Line 
1"""
2Tests for allmydata.util.base62.
3
4Ported to Python 3.
5"""
6
7import random, unittest
8
9from hypothesis import (
10    strategies as st,
11    given,
12)
13
14from allmydata.util import base62, mathutil
15
16def byteschr(x):
17    return bytes([x])
18
19def insecurerandstr(n):
20    return bytes(list(map(random.randrange, [0]*n, [256]*n)))
21
22class Base62(unittest.TestCase):
23    def _test_num_octets_that_encode_to_this_many_chars(self, chars, octets):
24        assert base62.num_octets_that_encode_to_this_many_chars(chars) == octets, "%s != %s <- %s" % (octets, base62.num_octets_that_encode_to_this_many_chars(chars), chars)
25
26    def _test_roundtrip(self, bs):
27        encoded = base62.b2a(bs)
28        decoded = base62.a2b(encoded)
29        self.assertEqual(decoded, bs)
30        self.assertIsInstance(encoded, bytes)
31        self.assertIsInstance(bs, bytes)
32        self.assertIsInstance(decoded, bytes)
33        # Encoded string only uses values from the base62 allowed characters:
34        self.assertFalse(set(encoded) - set(base62.chars))
35
36    @given(input_bytes=st.binary(max_size=100))
37    def test_roundtrip(self, input_bytes):
38        self._test_roundtrip(input_bytes)
39
40    def test_known_values(self):
41        """Known values to ensure the algorithm hasn't changed."""
42
43        def check_expected(plaintext, encoded):
44            result1 = base62.b2a(plaintext)
45            self.assertEqual(encoded, result1)
46            result2 = base62.a2b(encoded)
47            self.assertEqual(plaintext, result2)
48
49        check_expected(b"hello", b'7tQLFHz')
50        check_expected(b"", b'0')
51        check_expected(b"zzz", b'0Xg7e')
52        check_expected(b"\x36\xffWAT", b'49pq4mq')
53        check_expected(b"1234 22323", b'1A0afZe9mxSZpz')
54        check_expected(b"______", b'0TmAuCHJX')
55
56    def test_num_octets_that_encode_to_this_many_chars(self):
57        return self._test_num_octets_that_encode_to_this_many_chars(2, 1)
58        return self._test_num_octets_that_encode_to_this_many_chars(3, 2)
59        return self._test_num_octets_that_encode_to_this_many_chars(5, 3)
60        return self._test_num_octets_that_encode_to_this_many_chars(6, 4)
61
62    def test_ende_0x00(self):
63        return self._test_roundtrip(b'\x00')
64
65    def test_ende_0x01(self):
66        return self._test_roundtrip(b'\x01')
67
68    def test_ende_0x0100(self):
69        return self._test_roundtrip(b'\x01\x00')
70
71    def test_ende_0x000000(self):
72        return self._test_roundtrip(b'\x00\x00\x00')
73
74    def test_ende_0x010000(self):
75        return self._test_roundtrip(b'\x01\x00\x00')
76
77    def test_ende_randstr(self):
78        return self._test_roundtrip(insecurerandstr(2**4))
79
80    def test_ende_longrandstr(self):
81        return self._test_roundtrip(insecurerandstr(random.randrange(0, 2**10)))
82
83    def test_odd_sizes(self):
84        for j in range(2**6):
85            lib = random.randrange(1, 2**8)
86            numos = mathutil.div_ceil(lib, 8)
87            bs = insecurerandstr(numos)
88            # zero-out unused least-sig bits
89            if lib%8:
90                b = ord(bs[-1:])
91                b = b >> (8 - (lib%8))
92                b = b << (8 - (lib%8))
93                bs = bs[:-1] + byteschr(b)
94            asl = base62.b2a_l(bs, lib)
95            assert len(asl) == base62.num_chars_that_this_many_octets_encode_to(numos) # the size of the base-62 encoding must be just right
96            bs2l = base62.a2b_l(asl, lib)
97            assert len(bs2l) == numos # the size of the result must be just right
98            assert bs == bs2l
Note: See TracBrowser for help on using the repository browser.