j-crypto-change 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +4 -6
  2. package/src/index.js +101 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-crypto-change",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "This package was developed to enable programmers to encode and decode messages using a numerical cipher method.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -9,12 +9,10 @@
9
9
  "author": "Ejiro Jacob Oshevire",
10
10
  "license": "MIT",
11
11
  "keywords": [
12
- "cipher",
13
- "encryption",
14
- "caesar",
15
- "security",
16
12
  "encode",
17
13
  "decode",
18
- "createCipher"
14
+ "createCipher",
15
+ "playfairEncode",
16
+ "playfairDecode"
19
17
  ]
20
18
  }
package/src/index.js CHANGED
@@ -39,8 +39,109 @@ function createCipher(shift = 3) {
39
39
  };
40
40
  }
41
41
 
42
+ // Playfair Cipher
43
+
44
+ function generateKeySquare(key) {
45
+ const alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"; // no J
46
+ const seen = new Set();
47
+ let square = "";
48
+
49
+ // Add key characters first
50
+ for (let char of key.toUpperCase().replace(/J/g, "I")) {
51
+ if (!seen.has(char) && alphabet.includes(char)) {
52
+ seen.add(char);
53
+ square += char;
54
+ }
55
+ }
56
+
57
+ // Fill remaining letters
58
+ for (let char of alphabet) {
59
+ if (!seen.has(char)) {
60
+ seen.add(char);
61
+ square += char;
62
+ }
63
+ }
64
+
65
+ return square; // 25-character string representing 5x5 grid
66
+ }
67
+
68
+ function getPosition(square, char) {
69
+ const index = square.indexOf(char);
70
+ return { row: Math.floor(index / 5), col: index % 5 };
71
+ }
72
+
73
+ function prepareText(text) {
74
+ text = text
75
+ .toUpperCase()
76
+ .replace(/J/g, "I")
77
+ .replace(/[^A-Z]/g, "");
78
+
79
+ let pairs = [];
80
+ let i = 0;
81
+
82
+ while (i < text.length) {
83
+ let a = text[i];
84
+ let b = text[i + 1] || "X";
85
+
86
+ if (a === b) {
87
+ b = "X";
88
+ i++;
89
+ } else {
90
+ i += 2;
91
+ }
92
+
93
+ pairs.push([a, b]);
94
+ }
95
+
96
+ return pairs;
97
+ }
98
+
99
+ function playfairShift(square, a, b, direction) {
100
+ const posA = getPosition(square, a);
101
+ const posB = getPosition(square, b);
102
+
103
+ // Same row
104
+ if (posA.row === posB.row) {
105
+ return [
106
+ square[posA.row * 5 + ((posA.col + direction + 5) % 5)],
107
+ square[posB.row * 5 + ((posB.col + direction + 5) % 5)],
108
+ ];
109
+ }
110
+
111
+ // Same column
112
+ if (posA.col === posB.col) {
113
+ return [
114
+ square[((posA.row + direction + 5) % 5) * 5 + posA.col],
115
+ square[((posB.row + direction + 5) % 5) * 5 + posB.col],
116
+ ];
117
+ }
118
+
119
+ // Rectangle swap
120
+ return [square[posA.row * 5 + posB.col], square[posB.row * 5 + posA.col]];
121
+ }
122
+
123
+ function playfairEncode(text, key = "KEY") {
124
+ const square = generateKeySquare(key);
125
+ const pairs = prepareText(text);
126
+
127
+ return pairs
128
+ .map(([a, b]) => playfairShift(square, a, b, 1).join(""))
129
+ .join("");
130
+ }
131
+
132
+ function playfairDecode(text, key = "KEY") {
133
+ const square = generateKeySquare(key);
134
+ const pairs = prepareText(text);
135
+
136
+ return pairs
137
+ .map(([a, b]) => playfairShift(square, a, b, -1).join(""))
138
+ .join("");
139
+ }
140
+
42
141
  module.exports = {
43
142
  encode,
44
143
  decode,
45
144
  createCipher,
145
+ playfairEncode,
146
+ playfairDecode,
46
147
  };