Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ console.log(ceaser.encrypt("hello world"))
- Atbash Cipher
- Playfair Cipher
- Vigenere Cipher
- The Alphabet Cipher
- & more coming soon ...

#### Thanks for visiting (>'-'<)
2 changes: 2 additions & 0 deletions dist/Cipher.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { Caesar } from "./ciphers/Caesar.js"
import { Atbash } from "./ciphers/Atbash.js"
import { Playfair } from "./ciphers/Playfair.js"
import { Vigenere } from "./ciphers/Vigenere.js"
import { Alphabet } from "./ciphers/Alphabet.js"
export declare abstract class Cipher {
static Caesar: typeof Caesar
static Atbash: typeof Atbash
static Playfair: typeof Playfair
static Vigenere: typeof Vigenere
static Alphabet: typeof Alphabet
abstract encrypt(text: string): string
abstract decrypt(text: string): string
}
22 changes: 22 additions & 0 deletions dist/ciphers/Alphabet.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Cipher } from "../Cipher.js"
export declare class Alphabet extends Cipher {
private keyword
private static alphabet
constructor(keyword: string)
/**
* Encrypts a message using the Alphabet Cipher.
* @param message - The plaintext message to encrypt.
* @returns The encrypted ciphertext.
*/
encrypt(message: string): string
/**
* Decrypts a message using the Alphabet Cipher.
* @param ciphertext - The encrypted message to decrypt.
* @returns The original plaintext message.
*/
decrypt(ciphertext: string): string
/**
* Generates the Vigenère table for encoding and decoding.
*/
private static getVigenereTable
}
65 changes: 65 additions & 0 deletions dist/ciphers/Alphabet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Cipher } from "../Cipher.js"
export class Alphabet extends Cipher {
constructor(keyword) {
super()
this.keyword = keyword.toLowerCase()
}
/**
* Encrypts a message using the Alphabet Cipher.
* @param message - The plaintext message to encrypt.
* @returns The encrypted ciphertext.
*/
encrypt(message) {
message = message.toLowerCase()
const table = Alphabet.getVigenereTable()
let result = ""
for (let i = 0; i < message.length; i++) {
const msgChar = message[i]
const keyChar = this.keyword[i % this.keyword.length]
if (!Alphabet.alphabet.includes(msgChar)) {
result += msgChar // Preserve non-alphabet characters
continue
}
const row = Alphabet.alphabet.indexOf(keyChar)
const col = Alphabet.alphabet.indexOf(msgChar)
result += table[row][col]
}
return result
}
/**
* Decrypts a message using the Alphabet Cipher.
* @param ciphertext - The encrypted message to decrypt.
* @returns The original plaintext message.
*/
decrypt(ciphertext) {
ciphertext = ciphertext.toLowerCase()
const table = Alphabet.getVigenereTable()
let result = ""
for (let i = 0; i < ciphertext.length; i++) {
const cipherChar = ciphertext[i]
const keyChar = this.keyword[i % this.keyword.length]
if (!Alphabet.alphabet.includes(cipherChar)) {
result += cipherChar // Preserve non-alphabet characters
continue
}
const row = Alphabet.alphabet.indexOf(keyChar)
const col = table[row].indexOf(cipherChar)
result += Alphabet.alphabet[col]
}
return result
}
/**
* Generates the Vigenère table for encoding and decoding.
*/
static getVigenereTable() {
const table = []
for (let i = 0; i < 26; i++) {
table[i] = Alphabet.alphabet
.slice(i)
.split("")
.concat(Alphabet.alphabet.slice(0, i).split(""))
}
return table
}
}
Alphabet.alphabet = "abcdefghijklmnopqrstuvwxyz"
2 changes: 2 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Caesar } from "./ciphers/Caesar.js"
import { Atbash } from "./ciphers/Atbash.js"
import { Playfair } from "./ciphers/Playfair.js"
import { Vigenere } from "./ciphers/Vigenere.js"
import { Alphabet } from "./ciphers/Alphabet.js"
Cipher.Caesar = Caesar
Cipher.Atbash = Atbash
Cipher.Playfair = Playfair
Cipher.Vigenere = Vigenere
Cipher.Alphabet = Alphabet
export { Cipher }
2 changes: 2 additions & 0 deletions src/Cipher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { Caesar } from "./ciphers/Caesar.js"
import { Atbash } from "./ciphers/Atbash.js"
import { Playfair } from "./ciphers/Playfair.js"
import { Vigenere } from "./ciphers/Vigenere.js"
import { Alphabet } from "./ciphers/Alphabet.js"

export abstract class Cipher {
static Caesar: typeof Caesar
static Atbash: typeof Atbash
static Playfair: typeof Playfair
static Vigenere: typeof Vigenere
static Alphabet: typeof Alphabet

abstract encrypt(text: string): string
abstract decrypt(text: string): string
Expand Down
79 changes: 79 additions & 0 deletions src/ciphers/Alphabet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Cipher } from "../Cipher.js"

export class Alphabet extends Cipher {
private keyword: string
private static alphabet = "abcdefghijklmnopqrstuvwxyz"

constructor(keyword: string) {
super()
this.keyword = keyword.toLowerCase()
}

/**
* Encrypts a message using the Alphabet Cipher.
* @param message - The plaintext message to encrypt.
* @returns The encrypted ciphertext.
*/
encrypt(message: string): string {
message = message.toLowerCase()
const table = Alphabet.getVigenereTable()
let result = ""

for (let i = 0; i < message.length; i++) {
const msgChar = message[i]
const keyChar = this.keyword[i % this.keyword.length]

if (!Alphabet.alphabet.includes(msgChar)) {
result += msgChar // Preserve non-alphabet characters
continue
}

const row = Alphabet.alphabet.indexOf(keyChar)
const col = Alphabet.alphabet.indexOf(msgChar)
result += table[row][col]
}

return result
}

/**
* Decrypts a message using the Alphabet Cipher.
* @param ciphertext - The encrypted message to decrypt.
* @returns The original plaintext message.
*/
decrypt(ciphertext: string): string {
ciphertext = ciphertext.toLowerCase()
const table = Alphabet.getVigenereTable()
let result = ""

for (let i = 0; i < ciphertext.length; i++) {
const cipherChar = ciphertext[i]
const keyChar = this.keyword[i % this.keyword.length]

if (!Alphabet.alphabet.includes(cipherChar)) {
result += cipherChar // Preserve non-alphabet characters
continue
}

const row = Alphabet.alphabet.indexOf(keyChar)
const col = table[row].indexOf(cipherChar)
result += Alphabet.alphabet[col]
}

return result
}

/**
* Generates the Vigenère table for encoding and decoding.
*/
private static getVigenereTable(): string[][] {
const table: string[][] = []
for (let i = 0; i < 26; i++) {
table[i] = Alphabet.alphabet
.slice(i)
.split("")
.concat(Alphabet.alphabet.slice(0, i).split(""))
}
return table
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { Caesar } from "./ciphers/Caesar.js"
import { Atbash } from "./ciphers/Atbash.js"
import { Playfair } from "./ciphers/Playfair.js"
import { Vigenere } from "./ciphers/Vigenere.js"
import { Alphabet } from "./ciphers/Alphabet.js"

Cipher.Caesar = Caesar
Cipher.Atbash = Atbash
Cipher.Playfair = Playfair
Cipher.Vigenere = Vigenere
Cipher.Alphabet = Alphabet

export { Cipher }
10 changes: 10 additions & 0 deletions tests/alphabet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Cipher } from "../src/index"

test(`The Alphabet Cipher`, () => {
const alphabet = new Cipher.Alphabet("keyword")
const plaintext = "hello world"
const enc = alphabet.encrypt(plaintext)
const dec = alphabet.decrypt(enc)

expect(dec).toBe(plaintext)
})