# Hill Cipher and Caesar Cipher Implementation in JavaScript

> Discover JavaScript implementations of Hill Cipher and Caesar Cipher. Learn how these cryptographic algorithms use modular arithmetic and matrix multiplication for encryption in this clear guide.

- Repository: [Oleksii Trekhleb/javascript-algorithms](https://github.com/trekhleb/javascript-algorithms)
- Tags: deep-dive
- Published: 2026-02-24

---

**The trekhleb/javascript-algorithms repository implements both ciphers as pure functions under `src/algorithms/cryptography/`, using modular arithmetic for Caesar shifts and matrix multiplication via a shared linear algebra utility for Hill cipher encryption.**

The `trekhleb/javascript-algorithms` repository provides clean, educational implementations of classic **cryptographic algorithms** including the Caesar cipher and Hill cipher. Located under `src/algorithms/cryptography/`, these implementations demonstrate functional programming patterns while handling alphabet shifts, modular arithmetic, and linear algebra operations required for polygraphic substitution.

## Caesar Cipher Implementation

### Core Architecture and File Location

The Caesar cipher implementation resides in [`src/algorithms/cryptography/caesar-cipher/caesarCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/cryptography/caesar-cipher/caesarCipher.js). It defines a standard English alphabet array and exports two primary functions: `caesarCipherEncrypt` and `caesarCipherDecrypt`.

The implementation creates a simple alphabet array once:

```javascript
const englishAlphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');

```

### The getCipherMap Function

At the heart of the implementation is `getCipherMap(alphabet, shift)`, a helper that constructs a mapping object using `Array.prototype.reduce`. For each character, it calculates the target index as `(charIndex + shift) % alphabet.length`, handling negative shifts by adding `alphabet.length` when results fall below zero. This pure function enables both encryption and decryption via shift directionality.

### Encryption and Decryption Functions

The `caesarCipherEncrypt(str, shift, alphabet = englishAlphabet)` function normalizes input to lowercase, splits it into characters, substitutes each via the cipher map (preserving non-alphabet symbols), and joins the result. The `caesarCipherDecrypt` function reuses the same machinery but passes a negative shift to `getCipherMap`, effectively reversing the substitution.

```javascript
import {
  caesarCipherEncrypt,
  caesarCipherDecrypt,
} from './src/algorithms/cryptography/caesar-cipher/caesarCipher';

// Encrypt with a shift of 3
const secret = caesarCipherEncrypt('Hello, World!', 3);
console.log(secret); // khoor, zruog!

// Decrypt back to original
const plain = caesarCipherDecrypt(secret, 3);
console.log(plain); // hello, world!

```

## Hill Cipher Implementation

### Linear Algebra Foundation

The Hill cipher implementation in [`src/algorithms/cryptography/hill-cipher/hillCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/cryptography/hill-cipher/hillCipher.js) treats text as vectors and keys as matrices. It relies on the shared matrix utility at [`src/algorithms/math/matrix/Matrix.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/math/matrix/Matrix.js) for generation and multiplication operations, separating cryptographic logic from linear algebra mechanics.

### Key Matrix Generation

The `generateKeyMatrix` function accepts a `keyString` whose length must be a perfect square (yielding an N×N matrix). Using `mtrx.generate([size, size], callback)`, it populates each cell with values derived from character codes: `(keyString.codePointAt(idx)) % alphabetCodeShift`, where `alphabetCodeShift` is 65 (Unicode 'A'). This maps 'A'→0, 'B'→1, through 'Z'→25.

### Message Vector Processing

The `generateMessageVector` function produces a column vector from the plaintext message, applying the same modulo transformation to each character's code point. This ensures numerical compatibility with the key matrix for subsequent multiplication.

### Encryption Logic and Matrix Multiplication

The `hillCipherEncrypt(message, keyString)` function validates that inputs contain only letters (`/^[a-zA-Z]+$/`), generates the key matrix and message vector, and verifies dimensional compatibility (matrix side equals message length). It executes `mtrx.dot(keyMatrix, messageVector)` to produce the cipher vector, converting each result back to a character via `String.fromCharCode((item % englishAlphabetSize) + alphabetCodeShift)`.

```javascript
import { hillCipherEncrypt } from './src/algorithms/cryptography/hill-cipher/hillCipher';

// Key must be perfect square length; 4 letters = 2×2 matrix
const key = 'HILL';
const message = 'HELP';

const cipher = hillCipherEncrypt(message, key);
console.log(cipher); // → encrypted string (e.g., "RFKT")

```

### Decryption Status

The `hillCipherDecrypt` function exists only as a stub containing a `TODO` comment. Decryption requires calculating the modular multiplicative inverse of the key matrix determinant and applying matrix inversion modulo 26, which remains unimplemented in the current codebase.

## Shared Dependencies and Matrix Utilities

Both implementations leverage modular architecture. The Hill cipher specifically depends on [`src/algorithms/math/matrix/Matrix.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/math/matrix/Matrix.js), which exports `generate` and `dot` functions. This separation allows the cryptographic algorithm to focus on character encoding and validation while the matrix library handles two-dimensional array construction and multiplication operations.

## Summary

- The **Caesar cipher** in [`src/algorithms/cryptography/caesar-cipher/caesarCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/cryptography/caesar-cipher/caesarCipher.js) uses `getCipherMap` to create shift-based character mappings, supporting encryption and decryption via positive and negative shifts.
- The **Hill cipher** in [`src/algorithms/cryptography/hill-cipher/hillCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/cryptography/hill-cipher/hillCipher.js) implements polygraphic substitution using matrix multiplication via the shared [`Matrix.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/Matrix.js) utility, requiring perfect-square keys and letter-only input.
- Both algorithms follow functional programming patterns, operate as pure functions without side effects, and accept custom alphabets (Caesar) or modular arithmetic mappings (Hill).
- Hill cipher decryption remains unimplemented (stub with `TODO`), while Caesar cipher provides complete bidirectional functionality.

## Frequently Asked Questions

### How does the Caesar cipher handle negative shift values?

The `getCipherMap` function automatically accommodates negative shifts by adding `alphabet.length` to any negative intermediate result before applying the modulo operation. This ensures that shifting left (decrypting) works correctly without requiring separate logic for directionality.

### Why does the Hill cipher require a key of perfect square length?

The Hill cipher treats the key as an N×N matrix to perform linear algebra operations. The implementation in [`hillCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/hillCipher.js) calculates `matrixSize` as the square root of `keyString.length`, throwing an error if the result is not an integer. This dimensional requirement ensures the key matrix can multiply against the message vector.

### Can the Caesar cipher implementation work with non-English alphabets?

Yes. Both `caesarCipherEncrypt` and `caesarCipherDecrypt` accept an optional `alphabet` parameter that defaults to the English alphabet array. By passing a custom array of characters (e.g., Cyrillic, Greek, or extended ASCII), the cipher operates correctly on any defined symbol set using the same modular shift logic.

### Is the Hill cipher decryption functional in the current codebase?

No. The `hillCipherDecrypt` function in [`src/algorithms/cryptography/hill-cipher/hillCipher.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/cryptography/hill-cipher/hillCipher.js) exists only as a stub containing a `TODO` comment. Decryption requires calculating the modular multiplicative inverse of the key matrix determinant and applying matrix inversion modulo 26, which remains unimplemented.