1 import { TESIDCoder
} from "./tesid.js";
3 function assert_eq(a
, b
, msg
) {
4 if ((a
== null ? a : a
.toString()) !== (b
== null ? b : b
.toString())) {
6 "assert_eq failed" + (msg
? ": " + msg : "") +
13 function assert_ne(a
, b
, msg
) {
14 if ((a
== null ? a : a
.toString()) === (b
== null ? b : b
.toString())) {
16 "assert_ne failed" + (msg
? ": " + msg : "") +
23 function assert_throws(f
, msg_or_type
) {
28 if (msg_or_type
!= null) {
29 if (typeof msg_or_type
== "string") {
30 if (e
.toString() != msg_or_type
) {
31 throw new Error("Expected exception `" + msg_or_type
+ "`, but found exception `" + e
.toString() + "`");
34 if (!(e
instanceof msg_or_type
)) {
35 throw new Error("Expected exception of type " + msg_or_type
.name
+ ", but found exception `" + e
.toString() + "`");
41 throw new Error("Expected exception " +
42 (msg_or_type
== null ? "" :
43 typeof msg_or_type
== "string" ? "`" + msg_or_type
+ "`" :
44 "of type " + msg_or_type
.name
) +
45 "\nCode did not fail, but returned " + (x
== null ? x : x
.toString()));
48 function c(coder
, number
, string
) {
49 assert_eq(coder
.encode(number
), string
);
50 assert_eq(coder
.decode(string
), number
);
53 let coder
= new TESIDCoder("00000000000000000000000000000000");
54 c(coder
, 0n
, "4kcc");
55 c(coder
, 2n
**20n
- 1n
, "3rck");
56 c(coder
, 2n
**20n
, "ju2sgs");
57 c(coder
, 2n
**30n
- 1n
, "zangyh");
58 c(coder
, 2n
**30n
, "2aux4u3h");
59 c(coder
, 2n
**40n
- 1n
, "3cd7rc4h");
60 c(coder
, 2n
**40n
, "m8669y33k6");
61 c(coder
, 2n
**50n
- 1n
, "45e9rbrvvu");
62 c(coder
, 2n
**50n
, "t47yf553iv8t");
63 c(coder
, 2n
**60n
- 1n
, "cwd8t75epzje");
64 c(coder
, 2n
**60n
, "86hk4d8hj4yvcy");
65 c(coder
, 2n
**64n
- 1n
, "sirnf2k2d2m3bm");
66 c(coder
, 2n
**70n
- 1n
, "m77g4ezr3e8qay");
67 c(coder
, 2n
**70n
, "43xf2jj6r6qm8bw4");
68 c(coder
, 2n
**80n
- 1n
, "6h3wb7wytjr5tbrd");
69 c(coder
, 2n
**80n
, "4vumjq33d8iiwaharq");
70 c(coder
, 2n
**90n
- 1n
, "qd7s3csnc5yfrrud5t");
71 c(coder
, 2n
**90n
, "jd3vsipfn69ia72chuvx");
72 c(coder
, 2n
**100n
- 1n
, "628fg5kyid3z2vf2j4tf");
74 coder
= new TESIDCoder("000102030405060708090a0b0c0d0e0f");
75 c(coder
, 0n
, "w2ej");
76 c(coder
, 2n
**20n
- 1n
, "atcw");
77 c(coder
, 2n
**20n
, "8qwm6y");
78 c(coder
, 2n
**30n
- 1n
, "3eipc7");
79 c(coder
, 2n
**30n
, "n3md95r4");
80 c(coder
, 2n
**40n
- 1n
, "nnz4z5qb");
81 c(coder
, 2n
**40n
, "st9fvria97");
82 c(coder
, 2n
**50n
- 1n
, "qt42fug7hq");
83 c(coder
, 2n
**50n
, "dykqxtu2ieqi");
84 c(coder
, 2n
**60n
- 1n
, "h7rhnw6tfhun");
85 c(coder
, 2n
**60n
, "xb5c8isevin9i3");
86 c(coder
, 2n
**64n
- 1n
, "t62mijffzuvu4e");
87 c(coder
, 2n
**70n
- 1n
, "n6n8jq6ike9dnj");
88 c(coder
, 2n
**70n
, "zk9d3setywjf7uwu");
89 c(coder
, 2n
**80n
- 1n
, "bqqei5vmzkqjfru3");
90 c(coder
, 2n
**80n
, "z83vvq5u84sit9g7pd");
91 c(coder
, 2n
**90n
- 1n
, "cpawgn8snjvverxvmp");
92 c(coder
, 2n
**90n
, "397btwmkh5y7sjz2xu82");
93 c(coder
, 2n
**100n
- 1n
, "ia2bvpjaiju7g5uaxn5t");
95 // Encoding bad range or type
96 assert_throws(() => coder
.encode(-1n
), "RangeError: id out of range");
97 assert_throws(() => coder
.encode(2n
**100n
), "RangeError: id out of range");
98 assert_throws(() => coder
.encode(0), TypeError
); // “can't convert 0 to a BigInt” or similar.
100 // Test misencodings: 0 is w2ej, but if 0 were encrypted with n=15
101 // instead of n=10, it’d be m2eig5—so that value isn’t allowed.
102 assert_throws(() => coder
.decode("m2eig5"), "RangeError: bad TESID");
104 // … but slightly changed values are probably valid (since only one in
106 assert_eq(coder
.decode("m2eig6"), 473063752);
108 // Also a few more at the boundaries for confidence:
109 // 2²⁰−1 but encoded with n=15 instead of n=10
110 assert_throws(() => coder
.decode("vf5fem"), "RangeError: bad TESID");
111 // 2³⁰−1 but encoded with n=20 instead of n=15
112 assert_throws(() => coder
.decode("ixs6h9ma"), "RangeError: bad TESID");
113 // 2³⁰−1 but encoded with n=50 instead of n=10
114 assert_throws(() => coder
.decode("uhkprgrirp45pe54twsa"), "RangeError: bad TESID");
116 // Bad string lengths
117 assert_throws(() => coder
.decode(""), "RangeError: bad TESID");
118 assert_throws(() => coder
.decode("2"), "RangeError: bad TESID");
119 assert_throws(() => coder
.decode("22"), "RangeError: bad TESID");
120 assert_throws(() => coder
.decode("222"), "RangeError: bad TESID");
121 assert_throws(() => coder
.decode("22222"), "RangeError: bad TESID");
122 assert_throws(() => coder
.decode("2222222222222222222"), "RangeError: bad TESID");
123 assert_throws(() => coder
.decode("222222222222222222222"), "RangeError: bad TESID");
125 // … but just so it’s clear, ones are fine, it was just the lengths that were wrong.
126 c(coder
, 173734n
, "2222");
127 c(coder
, 592178178n
, "222222");
128 c(coder
, 111515659577240532774228475483n
, "22222222222222222222");
130 // Now time for some tagging.
131 function c2(coder
, number
, string
, sparsity
, discriminant
, split_assert
) {
132 assert_eq(coder
.encode(number
, sparsity
, discriminant
), string
);
133 assert_eq(coder
.decode(string
, sparsity
, discriminant
), number
);
134 let s
= coder
.splitDecode(string
, sparsity
);
135 split_assert(discriminant
, s
.discriminant
);
136 split_assert(number
, s
.id
);
139 c2(coder
, 0n
, "w2ej", 1n
, 0n
, assert_eq
);
140 c2(coder
, 0n
, "w6um", 1n
, 1n
, assert_ne
);
141 c2(coder
, 0n
, "x45g", 1n
, 2n
, assert_ne
);
143 c2(coder
, 0n
, "w2ej", 100n
, 0n
, assert_eq
);
144 c2(coder
, 0n
, "w6um", 100n
, 1n
, assert_eq
);
145 c2(coder
, 0n
, "x45g", 100n
, 2n
, assert_eq
);
146 c2(coder
, 1n
, "ypbn", 100n
, 0n
, assert_eq
);
147 c2(coder
, 1n
, "k9pw", 100n
, 1n
, assert_eq
);
148 c2(coder
, 1n
, "b7nc", 100n
, 2n
, assert_eq
);
149 c2(coder
, 2n
, "r9yc", 100n
, 0n
, assert_eq
);
150 c2(coder
, 2n
, "arf2", 100n
, 1n
, assert_eq
);
151 c2(coder
, 2n
, "z6wh", 100n
, 2n
, assert_eq
);
152 c(coder
, 0n
, "w2ej");
153 c(coder
, 1n
, "w6um");
154 c(coder
, 2n
, "x45g");
155 c(coder
, 100n
, "ypbn");
156 c(coder
, 101n
, "k9pw");
157 c(coder
, 102n
, "b7nc");
158 c(coder
, 200n
, "r9yc");
159 c(coder
, 201n
, "arf2");
160 c(coder
, 202n
, "z6wh");
161 // The highest sparsity that’s always valid given 64-bit discriminant and id (which is the case in the Rust implementation): 2³⁶ − 1
162 c2(coder
, 2n
**64n
-1n
, "fjwz5jk3p4gz9aqes22e", (1n
<<36n
) - 1n
, 2n
**64n
-1n
, assert_ne
);
163 c(coder
, 1267650600228229401427983728640n
, "fjwz5jk3p4gz9aqes22e");