33 private period: number;
52 private toCoordinates(plaintext:
string): number[][] {
54 const sanitized = this.sanitize(plaintext);
55 const coordinates: number[][] = [];
57 for (
const ch of sanitized) {
58 const encoded = poly.encode(ch).replace(/\s/g,
'');
59 const row = Number(encoded[0]);
60 const col = Number(encoded[1]);
62 coordinates.push([row, col, depth]);
75 private fromCoordinates(coords: number[][]):
string {
77 const output:
string[] = [];
79 for (
const [row, col] of coords) {
80 const code = `${row}${col}`;
81 output.push(poly.decode(code));
84 return output.join(
'');
94 encode(plaintext:
string):
string {
95 const coords = this.toCoordinates(plaintext);
96 const flattened = coords.flat();
97 const blocks: number[][] = [];
100 for (let i = 0; i < flattened.length; i += this.period * 3) {
101 blocks.push(flattened.slice(i, i +
this.period * 3));
104 const encodedCoords: number[][] = [];
107 for (
const block of blocks) {
108 const third = Math.ceil(block.length / 3);
110 for (let i = 0; i < third; i++) {
113 block[i + third] ?? 1,
114 block[i + 2 * third] ?? 1,
116 encodedCoords.push(triplet);
120 return this.fromCoordinates(encodedCoords);
130 decode(ciphertext:
string):
string {
131 const coords = this.toCoordinates(ciphertext);
132 const flattened = coords.flat();
133 const blocks: number[][] = [];
135 for (let i = 0; i < flattened.length; i += this.period * 3) {
136 blocks.push(flattened.slice(i, i +
this.period * 3));
139 const decodedCoords: number[][] = [];
141 for (
const block of blocks) {
142 const third = Math.ceil(block.length / 3);
144 for (let i = 0; i < third; i++) {
147 block[i + third] ?? 1,
148 block[i + 2 * third] ?? 1,
150 decodedCoords.push(triplet);
154 return this.fromCoordinates(decodedCoords);