Skip to content

Commit b4bbf26

Browse files
authored
feat: algoritma porta cipher (#391)
* add: swapCharFromPeriodicTable function * add: getCurrentColumnRow function * add: getColumn function * add: filterToAlphabetOnly function * add: filterToAlphabetOnly for string and keys input * add: groupOfString by the length of keys * add: change groupOfStrings to groupOfString * add: loop groupOfString and swap each Char based on key char * add: test encrypt and decrypt string with portaCipher * docs: filterToAlphabetOnly function * docs: getCurrentColumnRow function * docs: swapCharFromPeriodicTable function * docs: portaCipher function * docs: portaCipher function returns value explanation * docs: change to Indonesia * feat: change literal string to double quotes * feat: change groupOfString RegExp method to looping * docs: add porta cipher algorithm reference link
1 parent 7b7b409 commit b4bbf26

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

algorithm/cipher/porta.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @summary Implementasi Porta Cipher
3+
* @param {string} string
4+
* @param {string} keys
5+
* @description Porta Cipher adalah jenis cipher substitusi polialfabet yang ditemukan oleh Giovanni Battista della Porta. Porta chiper menggunakan 13 huruf alphabet (A-M) dan (N-Z) yang bersifat timbal balik.
6+
* @link Penjelasan lebih lanjut: http://practicalcryptography.com/ciphers/porta-cipher/
7+
* @link Implementasi berdasarkan: http://www.cryptogram.org/downloads/aca.info/ciphers/Porta.pdf
8+
* @returns string yang telah terenkripsi atau terdekripsi
9+
* @example portaCipher("hello world")
10+
* //=> "OYTUBCHJUQ"
11+
*/
12+
13+
function portaCipher(string, keys = "PORTA") {
14+
/**
15+
* @summary mengambil kolom berdasarkan index genap
16+
* @description contoh arrray [[A,B], [C,D], [E,F], ...]
17+
* - [A,B] index 0
18+
* - [C,D] index 2
19+
* - [E,F] index 4
20+
* @param {string} key
21+
* @returns
22+
*/
23+
function getColumn(key) {
24+
const charACode = 65;
25+
let temp = key.charCodeAt() - charACode;
26+
27+
return temp % 2 !== 0 ? --temp : temp;
28+
}
29+
30+
/**
31+
* @summary mengambil baris dari nomor kolom berdasarkan key
32+
* @param {string} key
33+
* @returns
34+
*/
35+
function getCurrentColumnRow(key) {
36+
const nToZ = "NOPQRSTUVWXYZ";
37+
const column = getColumn(key);
38+
const shiftLength = column / 2;
39+
const endOfShiftLength = nToZ.length + shiftLength;
40+
41+
return (
42+
nToZ.substring(shiftLength, endOfShiftLength) +
43+
nToZ.substring(0, shiftLength)
44+
);
45+
}
46+
47+
/**
48+
* @summary menukar huruf berdasarkan key di tabel
49+
* @param {string} key
50+
* @param {string} charToSwap
51+
* @returns
52+
*/
53+
function swapCharFromPeriodicTable(key, charToSwap) {
54+
const aToMColumn = "ABCDEFGHIJKLM";
55+
const keyColumn = getCurrentColumnRow(key);
56+
57+
return aToMColumn.includes(charToSwap)
58+
? keyColumn[aToMColumn.indexOf(charToSwap)]
59+
: aToMColumn[keyColumn.indexOf(charToSwap)];
60+
}
61+
62+
/**
63+
* @summary mengubah string menjadi alfabet saja
64+
* @description {ABCDEFGHIJKLMNOPQRSTUVWXYZ}
65+
* @param {string} key
66+
* @param {string} charToSwap
67+
* @returns
68+
*/
69+
function filterToAlphabetOnly(string) {
70+
return string
71+
.toUpperCase()
72+
.split(/[\W\d]/)
73+
.join("");
74+
}
75+
76+
const filteredString = filterToAlphabetOnly(string);
77+
const filteredKeys = filterToAlphabetOnly(keys);
78+
79+
const groupOfString = [];
80+
81+
for (let i = 0; i < filteredString.length; i += filteredKeys.length) {
82+
groupOfString.push(filteredString.substring(i, i + filteredKeys.length));
83+
}
84+
85+
let result = "";
86+
87+
for (let i = 0; i < groupOfString.length; i++) {
88+
const currentString = groupOfString[i];
89+
90+
for (let j = 0; j < currentString.length; j++) {
91+
result += swapCharFromPeriodicTable(filteredKeys[j], currentString[j]);
92+
}
93+
}
94+
95+
return result;
96+
}
97+
98+
console.log(portaCipher("Andika Eka Kurnia"));
99+
// UGYRXUYSWXAKFRN
100+
101+
console.log(portaCipher("UGYRXUYSWXAKFRN"));
102+
// ANDIKAEKAKURNIA
103+
104+
console.log(portaCipher("Andika Eka Kurnia", "DikDns"));
105+
// OJVWQWSOSYBIMZS
106+
107+
console.log(portaCipher("OJVWQWSOSYBIMZS", "DikDns"));
108+
// ANDIKAEKAKURNIA

0 commit comments

Comments
 (0)