3 from .. import TESIDCoder
6 class TESIDTests(unittest
.TestCase
):
8 def c(coder
: TESIDCoder
, number
: int, string
: str):
9 self
.assertEqual(coder
.encode(number
), string
)
10 self
.assertEqual(coder
.decode(string
), number
)
12 coder
= TESIDCoder('00000000000000000000000000000000')
14 c(coder
, 2**20 - 1 , '3rck')
15 c(coder
, 2**20 , 'ju2sgs')
16 c(coder
, 2**30 - 1 , 'zangyh')
17 c(coder
, 2**30 , '2aux4u3h')
18 c(coder
, 2**40 - 1 , '3cd7rc4h')
19 c(coder
, 2**40 , 'm8669y33k6')
20 c(coder
, 2**50 - 1 , '45e9rbrvvu')
21 c(coder
, 2**50 , 't47yf553iv8t')
22 c(coder
, 2**60 - 1 , 'cwd8t75epzje')
23 c(coder
, 2**60 , '86hk4d8hj4yvcy')
24 c(coder
, 2**64 - 1 , 'sirnf2k2d2m3bm')
25 c(coder
, 2**70 - 1 , 'm77g4ezr3e8qay')
26 c(coder
, 2**70 , '43xf2jj6r6qm8bw4')
27 c(coder
, 2**80 - 1 , '6h3wb7wytjr5tbrd')
28 c(coder
, 2**80 , '4vumjq33d8iiwaharq')
29 c(coder
, 2**90 - 1 , 'qd7s3csnc5yfrrud5t')
30 c(coder
, 2**90 , 'jd3vsipfn69ia72chuvx')
31 c(coder
, 2**100 - 1, '628fg5kyid3z2vf2j4tf')
33 coder
= TESIDCoder('000102030405060708090a0b0c0d0e0f')
35 c(coder
, 2**20 - 1 , 'atcw')
36 c(coder
, 2**20 , '8qwm6y')
37 c(coder
, 2**30 - 1 , '3eipc7')
38 c(coder
, 2**30 , 'n3md95r4')
39 c(coder
, 2**40 - 1 , 'nnz4z5qb')
40 c(coder
, 2**40 , 'st9fvria97')
41 c(coder
, 2**50 - 1 , 'qt42fug7hq')
42 c(coder
, 2**50 , 'dykqxtu2ieqi')
43 c(coder
, 2**60 - 1 , 'h7rhnw6tfhun')
44 c(coder
, 2**60 , 'xb5c8isevin9i3')
45 c(coder
, 2**64 - 1 , 't62mijffzuvu4e')
46 c(coder
, 2**70 - 1 , 'n6n8jq6ike9dnj')
47 c(coder
, 2**70 , 'zk9d3setywjf7uwu')
48 c(coder
, 2**80 - 1 , 'bqqei5vmzkqjfru3')
49 c(coder
, 2**80 , 'z83vvq5u84sit9g7pd')
50 c(coder
, 2**90 - 1 , 'cpawgn8snjvverxvmp')
51 c(coder
, 2**90 , '397btwmkh5y7sjz2xu82')
52 c(coder
, 2**100 - 1, 'ia2bvpjaiju7g5uaxn5t')
54 with self
.assertRaises(ValueError): coder
.encode(-1)
55 with self
.assertRaises(TypeError): coder
.encode(0.5)
56 with self
.assertRaises(ValueError): coder
.encode(2**100)
58 # Test misencodings: 0 is w2ej, but if 0 were encrypted with n=15
59 # instead of n=10, it’d be m2eig5—so that value isn’t allowed.
60 assert_overlong
= self
.assertRaises(ValueError, msg
='invalid TESID (overly long encoding)')
61 with assert_overlong
: coder
.decode('m2eig5')
63 # … but slightly changed values are probably valid (since only one in
65 self
.assertEqual(coder
.decode('m2eig6'), 473063752)
67 # Also a few more at the boundaries for confidence:
68 # 2²⁰−1 but encoded with n=15 instead of n=10
69 with assert_overlong
: coder
.decode('vf5fem')
70 # 2³⁰−1 but encoded with n=20 instead of n=15
71 with assert_overlong
: coder
.decode('ixs6h9ma')
72 # 2³⁰−1 but encoded with n=50 instead of n=10
73 with assert_overlong
: coder
.decode('uhkprgrirp45pe54twsa')
75 x
= self
.assertRaises(ValueError, msg
='invalid TESID (wrong length)')
76 with x
: coder
.decode('')
77 with x
: coder
.decode('2')
78 with x
: coder
.decode('22')
79 with x
: coder
.decode('222')
80 with x
: coder
.decode('22222')
81 with x
: coder
.decode('2222222222222222222')
82 with x
: coder
.decode('222222222222222222222')
84 # … but just so it’s clear, ones are fine, it was just the lengths that were wrong.
85 c(coder
, 173734, '2222')
86 c(coder
, 592178178, '222222')
87 c(coder
, 111515659577240532774228475483, '22222222222222222222')
89 # Now time for some tagging.
90 def c2(coder
: TESIDCoder
, sparsity
: int, discriminant
: int, split
, id: int, tesid
: str):
91 self
.assertEqual(coder
.encode(id, sparsity
=sparsity
, discriminant
=discriminant
), tesid
)
92 self
.assertEqual(coder
.decode(tesid
, sparsity
=sparsity
, discriminant
=discriminant
), id)
94 c2(coder
, sparsity
=1, discriminant
=0, split
=self
.assertEqual
, id=0, tesid
='w2ej')
95 c2(coder
, sparsity
=1, discriminant
=1, split
=self
.assertNotEqual
, id=0, tesid
='w6um')
96 c2(coder
, sparsity
=1, discriminant
=2, split
=self
.assertNotEqual
, id=0, tesid
='x45g')
98 c2(coder
, sparsity
=100, discriminant
=0, split
=self
.assertEqual
, id=0, tesid
='w2ej')
99 c2(coder
, sparsity
=100, discriminant
=1, split
=self
.assertEqual
, id=0, tesid
='w6um')
100 c2(coder
, sparsity
=100, discriminant
=2, split
=self
.assertEqual
, id=0, tesid
='x45g')
101 c2(coder
, sparsity
=100, discriminant
=0, split
=self
.assertEqual
, id=1, tesid
='ypbn')
102 c2(coder
, sparsity
=100, discriminant
=1, split
=self
.assertEqual
, id=1, tesid
='k9pw')
103 c2(coder
, sparsity
=100, discriminant
=2, split
=self
.assertEqual
, id=1, tesid
='b7nc')
104 c2(coder
, sparsity
=100, discriminant
=0, split
=self
.assertEqual
, id=2, tesid
='r9yc')
105 c2(coder
, sparsity
=100, discriminant
=1, split
=self
.assertEqual
, id=2, tesid
='arf2')
106 c2(coder
, sparsity
=100, discriminant
=2, split
=self
.assertEqual
, id=2, tesid
='z6wh')
110 c(coder
, 100, 'ypbn')
111 c(coder
, 101, 'k9pw')
112 c(coder
, 102, 'b7nc')
113 c(coder
, 200, 'r9yc')
114 c(coder
, 201, 'arf2')
115 c(coder
, 202, 'z6wh')
116 # The highest sparsity that’s always valid given 64-bit discriminant and id (which is the case in the Rust implementation): 2³⁶ − 1
117 c2(coder
, sparsity
=(1<<36) - 1, discriminant
=2**64 - 1, split
=self
.assertNotEqual
, id=2**64 - 1, tesid
='fjwz5jk3p4gz9aqes22e')
118 c(coder
, 1267650600228229401427983728640, 'fjwz5jk3p4gz9aqes22e')