42 private getOrder(key:
string =
""): number[] {
43 const cleanKey = this.sanitize(key);
44 const indexedChars: { ch:
string; i: number }[] = [];
46 for (let i = 0; i < cleanKey.length; i++) {
47 indexedChars.push({ ch: cleanKey[i], i });
50 indexedChars.sort((a, b) => a.ch.localeCompare(b.ch));
52 const order: number[] = [];
53 for (
const item of indexedChars) {
68 encode(plainText:
string =
"", key:
string =
""):
string {
69 const order = this.getOrder(key);
70 const cols = order.length;
71 const rows = Math.ceil(plainText.length / cols);
72 const grid:
string[] = Array(cols).fill(
"");
74 for (let i = 0; i < plainText.length; i++) {
75 const colIndex = i % cols;
76 grid[colIndex] += plainText[i];
80 for (
const colIndex of order) {
81 output += grid[colIndex];
95 decode(cipherText:
string =
"", key:
string =
""):
string {
96 const order = this.getOrder(key);
97 const cols = order.length;
98 const rows = Math.ceil(cipherText.length / cols);
101 const colLengths: number[] = Array(cols).fill(Math.floor(cipherText.length / cols));
102 let remainder = cipherText.length - colLengths.reduce((sum, len) => sum + len, 0);
103 for (let i = 0; i < remainder; i++) {
108 const columns:
string[] = Array(cols).fill(
"");
110 for (let i = 0; i < cols; i++) {
111 const colIndex = order[i];
112 columns[colIndex] = cipherText.substr(pos, colLengths[i]);
113 pos += colLengths[i];
118 for (let r = 0; r < rows; r++) {
119 for (let c = 0; c < cols; c++) {
120 output += columns[c][r] ??
"";