/*
invalid => return 1
invlaid => digit key => only contain alpha
3. should not contatin repeated character
get the key
validate
get plainTex
encipher
print cipher text
key validity:
1. check key length -> key must conatin 26, return 1 for err
2. check for non alphabetic char
3. check for repeated char
getString from user
then encipher text
encipher
1. for each alpha betic character, determine what letter it map to
2. preserve the case
3. leave non alpha betic character as it
eg:
1. Should take any char i.e upper and lower case
*/
class Cipher {
constructor() {
this.myMap = new Map();
this.cipherText = '';
this.inputText = '';
}
isLowerCaseChar(char) {
return 96 < char.charCodeAt(0) && char.charCodeAt(0) < 123;
}
isUpperCaseChar(char) {
return 64 < char.charCodeAt(0) && char.charCodeAt(0) < 91;
}
isChar(char) {
return this.isLowerCaseChar(char) || this.isUpperCaseChar(char);
}
validate(key) {
/*
key validity:
1. check key length -> key must conatin 26, return 1 for err
2. check for non alphabetic char
3. check for repeated char
*/
const myMap = new Map();
if (!key || key.length < 26) {
return {
status: 1,
message: 'key must conatin 26 chars',
};
}
for (let i = 0; i < key.length; i++) {
if (myMap.has(key[i])) {
return {
status: 1,
message: 'Only unique keys are allowed',
};
}
// if only alphabetic then we process it
if (!this.isChar(key[i])) {
return {
error: key[i],
status: 1,
message: 'Only alphabetic characters are allowed',
};
}
}
return {
status: -1,
};
}
setEncipher(key) {
/*
H -> V
E -> K
L -> X
L -> X
O -> N
vkxxn
hello
VKXXN
HELLO
{
0 : J
1 : T
4: K
...
7: V
12: X
15: N
26: j
27: t
33: v
38:x
}
*/
// create the enciipher
for (let i = 0; i < key.length; i++) {
this.myMap.set(i, key[i]);
this.myMap.set(i + 26, key[i].toLowerCase());
}
}
takeInputAndProcess(plainText) {
let result = '';
for (let i = 0; i < plainText.length; i++) {
const currentChar = plainText[i];
if (this.isChar(currentChar)) {
// H => 7, h => 33
//if it's upper case then
if (this.isUpperCaseChar(currentChar)) {
const position = currentChar.charCodeAt(0) - 65;
// console.log('----> ', this.myMap.get(position));
result += this.myMap.get(position);
} else {
const position = currentChar.charCodeAt(0) - 97 + 26;
result += this.myMap.get(position);
}
} else {
result += currentChar;
}
}
this.cipherText = result;
this.inputText = plainText;
}
main(key, plainText) {
const flag = this.validate(key);
// 1 is validation error
if (flag.status === 1) {
return flag;
}
this.setEncipher(key);
this.takeInputAndProcess(plainText);
return this.getResult();
}
getResult() {
return this.cipherText;
}
}
let program = new Cipher();
/*
ABCDEFGHIJKLMNOPQRSTUVWXYZ
012345678901234567890123456789
NQXPOMAFTRHLZGECYJIUWSKDVB
BEES
QOOI
anurag
ngwjna
*/
console.log(program.main('nQXPOMAFTRHLZGECYJIUWSKDVB', 'Anu-- rag'));
https://cs50.harvard.edu/x/2025/psets/2/substitution/
/* invalid => return 1 invlaid => digit key => only contain alpha 3. should not contatin repeated character get the key validate get plainTex encipher print cipher text key validity: 1. check key length -> key must conatin 26, return 1 for err 2. check for non alphabetic char 3. check for repeated char getString from user then encipher text encipher 1. for each alpha betic character, determine what letter it map to 2. preserve the case 3. leave non alpha betic character as it eg: 1. Should take any char i.e upper and lower case */ class Cipher { constructor() { this.myMap = new Map(); this.cipherText = ''; this.inputText = ''; } isLowerCaseChar(char) { return 96 < char.charCodeAt(0) && char.charCodeAt(0) < 123; } isUpperCaseChar(char) { return 64 < char.charCodeAt(0) && char.charCodeAt(0) < 91; } isChar(char) { return this.isLowerCaseChar(char) || this.isUpperCaseChar(char); } validate(key) { /* key validity: 1. check key length -> key must conatin 26, return 1 for err 2. check for non alphabetic char 3. check for repeated char */ const myMap = new Map(); if (!key || key.length < 26) { return { status: 1, message: 'key must conatin 26 chars', }; } for (let i = 0; i < key.length; i++) { if (myMap.has(key[i])) { return { status: 1, message: 'Only unique keys are allowed', }; } // if only alphabetic then we process it if (!this.isChar(key[i])) { return { error: key[i], status: 1, message: 'Only alphabetic characters are allowed', }; } } return { status: -1, }; } setEncipher(key) { /* H -> V E -> K L -> X L -> X O -> N vkxxn hello VKXXN HELLO { 0 : J 1 : T 4: K ... 7: V 12: X 15: N 26: j 27: t 33: v 38:x } */ // create the enciipher for (let i = 0; i < key.length; i++) { this.myMap.set(i, key[i]); this.myMap.set(i + 26, key[i].toLowerCase()); } } takeInputAndProcess(plainText) { let result = ''; for (let i = 0; i < plainText.length; i++) { const currentChar = plainText[i]; if (this.isChar(currentChar)) { // H => 7, h => 33 //if it's upper case then if (this.isUpperCaseChar(currentChar)) { const position = currentChar.charCodeAt(0) - 65; // console.log('----> ', this.myMap.get(position)); result += this.myMap.get(position); } else { const position = currentChar.charCodeAt(0) - 97 + 26; result += this.myMap.get(position); } } else { result += currentChar; } } this.cipherText = result; this.inputText = plainText; } main(key, plainText) { const flag = this.validate(key); // 1 is validation error if (flag.status === 1) { return flag; } this.setEncipher(key); this.takeInputAndProcess(plainText); return this.getResult(); } getResult() { return this.cipherText; } } let program = new Cipher(); /* ABCDEFGHIJKLMNOPQRSTUVWXYZ 012345678901234567890123456789 NQXPOMAFTRHLZGECYJIUWSKDVB BEES QOOI anurag ngwjna */ console.log(program.main('nQXPOMAFTRHLZGECYJIUWSKDVB', 'Anu-- rag'));