Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add Substitution Cipher algorithm and tests#1773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
mmohamedkhaled wants to merge10 commits intoTheAlgorithms:master
base:master
Choose a base branch
Loading
frommmohamedkhaled:add-substitution-cipher
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
10 commits
Select commitHold shift + click to select a range
c93cda3
feat: add Substitution Cipher algorithm and tests
mmohamedkhaledApr 4, 2025
9f44c2f
fix: correct import path in SubstitutionCipher test
mmohamedkhaledApr 4, 2025
417fb61
fix: correct casing in import path for CI compatibility
mmohamedkhaledApr 4, 2025
73c15ce
fix: correct import path and folder name for CI
mmohamedkhaledApr 4, 2025
7adf020
fix: update import path in SubstitutionCipher test for correct folder…
mmohamedkhaledApr 4, 2025
56542d6
fix: update import path in SubstitutionCipher test for correct folder…
mmohamedkhaledApr 4, 2025
5f1ed3e
removed
mmohamedkhaledApr 4, 2025
c4035de
added Substitution Cipher and its test
mmohamedkhaledApr 4, 2025
b9432a0
edited the style
mmohamedkhaledApr 4, 2025
25add22
"test: add missing coverage for Substitution Cipher decryption edge c…
mmohamedkhaledApr 4, 2025
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
59 changes: 59 additions & 0 deletionsCiphers/SubstitutionCipher.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
/**
* Substitution Cipher
*
* A monoalphabetic substitution cipher replaces each letter of the plaintext
* with another letter based on a fixed permutation (key) of the alphabet.
* https://en.wikipedia.org/wiki/Substitution_cipher
*/

const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const defaultKey = 'QWERTYUIOPASDFGHJKLZXCVBNM'

/**
* Encrypts a string using a monoalphabetic substitution cipher
* @param {string} text - The text to encrypt
* @param {string} key - The substitution key (must be 26 uppercase letters)
* @returns {string}
*/
export function substitutionCipherEncryption(text, key = defaultKey) {
if (key.length !== 26 || !/^[A-Z]+$/.test(key)) {
throw new RangeError('Key must be 26 uppercase English letters.')
}

let result = ''
const textUpper = text.toUpperCase()
for (let i = 0; i < textUpper.length; i++) {
const char = textUpper[i]
const index = alphabet.indexOf(char)
if (index !== -1) {
result += key[index]
} else {
result += char
}
}
return result
}
/**
* Decrypts a string encrypted with the substitution cipher
* @param {string} text - The encrypted text
* @param {string} key - The substitution key used during encryption
* @returns {string}
*/
export function substitutionCipherDecryption(text, key = defaultKey) {
if (key.length !== 26 || !/^[A-Z]+$/.test(key)) {
throw new RangeError('Key must be 26 uppercase English letters.')
}

let result = ''
const textUpper = text.toUpperCase()
for (let i = 0; i < textUpper.length; i++) {
const char = textUpper[i]
const index = key.indexOf(char)
if (index !== -1) {
result += alphabet[index]
} else {
result += char
}
}
return result
}
44 changes: 44 additions & 0 deletionsCiphers/test/SubstitutionCipher.test.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
import { describe, it, expect } from 'vitest'
import {
substitutionCipherEncryption,
substitutionCipherDecryption
} from '../SubstitutionCipher.js'

describe('Substitution Cipher', () => {
const key = 'QWERTYUIOPASDFGHJKLZXCVBNM'

it('correctly encrypts a message', () => {
const encrypted = substitutionCipherEncryption('HELLO WORLD', key)
expect(encrypted).toBe('ITSSG VGKSR')
})

it('correctly decrypts a message', () => {
const decrypted = substitutionCipherDecryption('ITSSG VGKSR', key)
expect(decrypted).toBe('HELLO WORLD')
})

it('handles non-alphabetic characters', () => {
const encrypted = substitutionCipherEncryption('Test! 123', key)
expect(encrypted).toBe('ZTLZ! 123')
})

it('throws error for invalid key', () => {
expect(() => substitutionCipherEncryption('HELLO', 'BADKEY')).toThrow(
RangeError
)
})
it('encrypts using default key if none provided', () => {
const encrypted = substitutionCipherEncryption('HELLO WORLD')
expect(encrypted).toBe('ITSSG VGKSR')
})

it('decrypts using default key if none provided', () => {
const decrypted = substitutionCipherDecryption('ITSSG VGKSR')
expect(decrypted).toBe('HELLO WORLD')
})

it('throws error for invalid key in decryption', () => {
expect(() => substitutionCipherDecryption('HELLO', 'BADKEY')).toThrow(RangeError)
})

})
4 changes: 2 additions & 2 deletionsMaths/MobiusFunction.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,6 +28,6 @@ export const mobiusFunction = (number) => {
return primeFactorsArray.length !== new Set(primeFactorsArray).size
? 0
: primeFactorsArray.length % 2 === 0
? 1
: -1
? 1
: -1
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp