> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/cis/practical-1-caesar-cipher-substitution-technique.md).

# Practical 1 — Caesar Cipher (Substitution Technique)

### Aim

To implement the Caesar Cipher, a classical substitution cipher, for encrypting text using Python.

### Concept

The Caesar Cipher is one of the earliest known encryption techniques, named after Julius Caesar, who reportedly used it to communicate with his generals. It is a **substitution cipher**: every letter in the plaintext is shifted a fixed number of positions (the **key** or **shift**) down the alphabet.

For example, with a shift of 3:

* `A` → `D`
* `B` → `E`
* `Z` → `C` (wraps around back to the start of the alphabet)

Non-alphabetic characters (spaces, numbers, punctuation) are typically left unchanged.

### Mathematical Formula

Let each letter be represented by a number from 0-25 (A=0, B=1, ..., Z=25). If `x` is the numeric value of a plaintext letter and `k` is the shift key:

**Encryption:**

```
E(x) = (x + k) mod 26
```

**Decryption:**

```
D(x) = (x - k) mod 26
```

The `mod 26` ensures the result "wraps around" the 26 letters of the alphabet — e.g. shifting `Z` (25) by 3 gives `(25 + 3) mod 26 = 2`, which is `C`.

Since Python's `chr()` and `ord()` functions work with full ASCII codes (not 0-25 directly), the code adjusts by subtracting the ASCII base value (`65` for uppercase `A`, `97` for lowercase `a`) before applying the modulo, then adding it back — this re-bases the alphabet to start at 0 before doing the wraparound math, and shifts it back to correct ASCII afterward.

### Python Code

```python
def caesar_encrypt(text, shift):
    result = ''
    for i in range(len(text)):
        char = text[i]
        if char.isupper():
            result += chr((ord(char) + shift - 65) % 26 + 65)
        elif char.islower():
            result += chr((ord(char) + shift - 97) % 26 + 97)
        else:
            result += char
    return result

num = int(input("Enter the amount of names to cipher"))
message = [0] * num
shift_key = 0
for name in range(len(message)):
    message[name] = input(f"Name {name+1}:")
shift_key = int(input("Enter the shift key for Caesar Cipher:"))
for name in range(len(message)):
    print("Original: ", message[name])
    print("Caesar Cipher (Substitution): ", caesar_encrypt(message[name], shift_key))
```

### Line-by-Line Explanation

#### The `caesar_encrypt` function

```python
def caesar_encrypt(text, shift):
```

Defines a function named `caesar_encrypt` that takes two parameters: `text` (the string to encrypt) and `shift` (the numeric key — how many positions to shift each letter).

```python
    result = ''
```

Creates an empty string `result`. This will be built up character-by-character to hold the final encrypted output.

```python
    for i in range(len(text)):
```

Loops over every index `i` from `0` to `len(text) - 1`, i.e. visits every character position in the input string one at a time.

```python
        char = text[i]
```

Extracts the character at position `i` from `text` and stores it in the variable `char`, so the rest of the loop body can work with it.

```python
        if char.isupper():
```

Checks whether `char` is an **uppercase** letter (A-Z). Python's built-in `.isupper()` string method returns `True` only for uppercase alphabetic characters.

```python
            result += chr((ord(char) + shift - 65) % 26 + 65)
```

This is the core Caesar cipher math for uppercase letters, applied step by step:

* `ord(char)` converts the character to its ASCII numeric code (e.g. `ord('A')` is `65`).
* `ord(char) - 65` re-bases the letter so `A` becomes `0`, `B` becomes `1`, ..., `Z` becomes `25` (this matches the `x` in the formula above).

  Wait — in the code the order is `ord(char) + shift - 65`, which is algebraically identical to `(ord(char) - 65) + shift`, i.e. "re-base to 0-25, **then** add the shift." Addition is commutative, so the result is the same either way.
* `% 26` wraps the result around the alphabet, so if the shifted value goes past 25 (i.e. past `Z`), it wraps back to the start (`0`, i.e. `A`).
* `+ 65` converts the number back to a proper ASCII code by re-adding the base offset for uppercase letters.
* `chr(...)` converts that final ASCII number back into an actual character.
* `result += ...` appends this new, shifted character onto the end of `result`.

```python
        elif char.islower():
```

If `char` was **not** uppercase, this checks whether it is **lowercase** (a-z) instead, using `.islower()`.

```python
            result += chr((ord(char) + shift - 97) % 26 + 97)
```

Identical logic to the uppercase case, but using `97` (the ASCII code for lowercase `a`) instead of `65`, since lowercase letters occupy a different range of ASCII codes.

```python
        else:
            result += char
```

If the character is neither uppercase nor lowercase (e.g. a space, digit, or punctuation mark), it is **not** shifted — it's appended to `result` unchanged. This keeps things like spaces and punctuation readable in the output.

```python
    return result
```

Once the loop has processed every character, the function returns the fully-built encrypted string.

#### The main program

```python
num = int(input("Enter the amount of names to cipher"))
```

Prompts the user to type how many names/messages they want to encrypt, and converts their text input into an integer with `int()`.

```python
message = [0] * num
```

Creates a list called `message` with `num` elements, all initially set to `0` — this pre-allocates space to store each name that will be entered next.

```python
shift_key = 0
```

Initializes a variable `shift_key` to `0`. This will later be overwritten with the user's actual chosen shift value; it's just a starting placeholder.

```python
for name in range(len(message)):
    message[name] = input(f"Name {name+1}:")
```

Loops through each index of the `message` list and asks the user to type a name for each slot. `f"Name {name+1}:"` builds a prompt like `Name 1:`, `Name 2:`, etc. (adding `1` so the prompt starts counting from 1, not 0). Each typed name replaces the placeholder `0` at that index.

```python
shift_key = int(input("Enter the shift key for Caesar Cipher:"))
```

Asks the user for the shift value to use for encryption and converts it to an integer.

```python
for name in range(len(message)):
    print("Original: ", message[name])
    print("Caesar Cipher (Substitution): ", caesar_encrypt(message[name], shift_key))
```

Loops through every stored name again. For each one, it:

* Prints the original (unencrypted) name.
* Calls `caesar_encrypt()` with that name and the chosen `shift_key`, and prints the resulting encrypted string.

### Sample Output

```
Enter the amount of names to cipher: 1
Name 1: Hello
Enter the shift key for Caesar Cipher: 3
Original:  Hello
Caesar Cipher (Substitution):  Khoor
```

### Conclusion

The Caesar Cipher demonstrates a basic substitution technique where each letter is systematically replaced based on a numeric shift key, using modular arithmetic to wrap around the alphabet.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/cis/practical-1-caesar-cipher-substitution-technique.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
