cipher-solver


Namecipher-solver JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://github.com/alimony/cipher_solver
SummaryAlgorithm for solving simple, monoalphabetic substitution ciphers
upload_time2025-07-28 08:39:40
maintainerNone
docs_urlNone
authorMarkus Amalthea Magnuson
requires_python>=3.6
licenseMIT
keywords monoalphabetic-substitution-cipher substitution-cipher cipher
VCS
bugtrack_url
requirements numpy
Travis-CI No Travis.
coveralls test coverage
            # Substitution Cipher Solver

### Algorithm for solving simple, monoalphabetic substitution ciphers

This is Python implementation of the algorithm for solving
[simple, monoalphabetic substitution ciphers](https://en.wikipedia.org/wiki/Substitution_cipher#Simple_substitution)
described in the paper
[“A Fast Method for the Cryptanalysis of Substitution Ciphers”](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.55.89&rep=rep1&type=pdf)
by Thomas Jakobsen. The main difference from the paper is that random key swaps are used
instead of a deterministic series of swaps since it yields better results, but the
original method is included and can be used as an option.

#### Installing

    pip install cipher_solver

#### API

```python
class SimpleSolver:
    """Simple substitution cipher solver."""

    def __init__(self, ciphertext):
        """Create new solver.

        Creates a new cipher solver from an initial ciphertext.
        """

    def solve(self, method="random"):
        """Solve the cipher.

        Run the solver and save the resulting decryption key.
        """

    def plaintext(self):
        """Return a plaintext using the current decryption key."""

    def reset(self):
        """Reset the solver to its initial state.

        Set the decryption key to its initial state, effectively starting over.
        """
```
See the [documentation](https://alimony.github.io/cipher_solver/) for full description
of methods and their parameters.

#### Requirements

* numpy

#### Usage

```python
from cipher_solver.simple import SimpleSolver

# Solve a cipher.
s = SimpleSolver("U kn kgmhksz tkm exmpb xt Gxesxe.")
s.solve()
print(s.plaintext())  # "I am already far north of London."

s.reset()  # Discard current solution to start over.
s.solve()
print(s.plaintext())  # We have an alternative solution now.

print(s.decryption_key())  # "goaskbihxvrldepfwntmzqjucy"

# Solve using the original key swap method instead.
d = SimpleSolver("U kn kgmhksz tkm exmpb xt Gxesxe.", method="deterministic")
d.solve()
print(s.plaintext())
```

Note, however, that the above ciphertext is too short to give any meaningful results.
A length of at least a few hundred letters is preferred to solve a cipher. See below for
an example using an included sample text.

#### CLI

A simple command-line interface is included. To solve a cipher, put it into a text file
and run:

```bash
cipher_solver <path_to_ciphertext_file>
```

Example:

```bash
cipher_solver texts/26_char_key/ciphertexts/ciphertext_frankenstein_sample.txt
```

Since the algorithm involves [hill climbing](https://en.wikipedia.org/wiki/Hill_climbing)
and randomness you might sometimes end up with complete gibberish, just run the script
again and the next result should be better.

#### Running tests

    make test

#### Checking coverage

    make coverage

(Requires the `coverage` package.)

#### Generating documentation

    make docs

(Requires the `pdoc3` package.)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/alimony/cipher_solver",
    "name": "cipher-solver",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "monoalphabetic-substitution-cipher substitution-cipher cipher",
    "author": "Markus Amalthea Magnuson",
    "author_email": "markus@polyscopic.works",
    "download_url": "https://files.pythonhosted.org/packages/6c/bd/39bb025690030ff5c9318ab4cef76aea3138d3211e95da7286ce438194bb/cipher_solver-1.0.2.tar.gz",
    "platform": null,
    "description": "# Substitution Cipher Solver\n\n### Algorithm for solving simple, monoalphabetic substitution ciphers\n\nThis is Python implementation of the algorithm for solving\n[simple, monoalphabetic substitution ciphers](https://en.wikipedia.org/wiki/Substitution_cipher#Simple_substitution)\ndescribed in the paper\n[\u201cA Fast Method for the Cryptanalysis of Substitution Ciphers\u201d](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.55.89&rep=rep1&type=pdf)\nby Thomas Jakobsen. The main difference from the paper is that random key swaps are used\ninstead of a deterministic series of swaps since it yields better results, but the\noriginal method is included and can be used as an option.\n\n#### Installing\n\n    pip install cipher_solver\n\n#### API\n\n```python\nclass SimpleSolver:\n    \"\"\"Simple substitution cipher solver.\"\"\"\n\n    def __init__(self, ciphertext):\n        \"\"\"Create new solver.\n\n        Creates a new cipher solver from an initial ciphertext.\n        \"\"\"\n\n    def solve(self, method=\"random\"):\n        \"\"\"Solve the cipher.\n\n        Run the solver and save the resulting decryption key.\n        \"\"\"\n\n    def plaintext(self):\n        \"\"\"Return a plaintext using the current decryption key.\"\"\"\n\n    def reset(self):\n        \"\"\"Reset the solver to its initial state.\n\n        Set the decryption key to its initial state, effectively starting over.\n        \"\"\"\n```\nSee the [documentation](https://alimony.github.io/cipher_solver/) for full description\nof methods and their parameters.\n\n#### Requirements\n\n* numpy\n\n#### Usage\n\n```python\nfrom cipher_solver.simple import SimpleSolver\n\n# Solve a cipher.\ns = SimpleSolver(\"U kn kgmhksz tkm exmpb xt Gxesxe.\")\ns.solve()\nprint(s.plaintext())  # \"I am already far north of London.\"\n\ns.reset()  # Discard current solution to start over.\ns.solve()\nprint(s.plaintext())  # We have an alternative solution now.\n\nprint(s.decryption_key())  # \"goaskbihxvrldepfwntmzqjucy\"\n\n# Solve using the original key swap method instead.\nd = SimpleSolver(\"U kn kgmhksz tkm exmpb xt Gxesxe.\", method=\"deterministic\")\nd.solve()\nprint(s.plaintext())\n```\n\nNote, however, that the above ciphertext is too short to give any meaningful results.\nA length of at least a few hundred letters is preferred to solve a cipher. See below for\nan example using an included sample text.\n\n#### CLI\n\nA simple command-line interface is included. To solve a cipher, put it into a text file\nand run:\n\n```bash\ncipher_solver <path_to_ciphertext_file>\n```\n\nExample:\n\n```bash\ncipher_solver texts/26_char_key/ciphertexts/ciphertext_frankenstein_sample.txt\n```\n\nSince the algorithm involves [hill climbing](https://en.wikipedia.org/wiki/Hill_climbing)\nand randomness you might sometimes end up with complete gibberish, just run the script\nagain and the next result should be better.\n\n#### Running tests\n\n    make test\n\n#### Checking coverage\n\n    make coverage\n\n(Requires the `coverage` package.)\n\n#### Generating documentation\n\n    make docs\n\n(Requires the `pdoc3` package.)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Algorithm for solving simple, monoalphabetic substitution ciphers",
    "version": "1.0.2",
    "project_urls": {
        "Documentation": "https://alimony.github.io/cipher_solver/",
        "Homepage": "https://github.com/alimony/cipher_solver",
        "Source": "https://github.com/alimony/cipher_solver",
        "Tracker": "https://github.com/alimony/cipher_solver/issues"
    },
    "split_keywords": [
        "monoalphabetic-substitution-cipher",
        "substitution-cipher",
        "cipher"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "357ea549abe27dd8e696c8dd239b62dd2e18e87a9225a1353802c37c702cf7c6",
                "md5": "66e2a2043507a7b79ccd6b0a8405dd05",
                "sha256": "b6419461356465c2f67ff8383156055f91bd6eead1020b684b1a201279b54cea"
            },
            "downloads": -1,
            "filename": "cipher_solver-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "66e2a2043507a7b79ccd6b0a8405dd05",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 11977,
            "upload_time": "2025-07-28T08:39:39",
            "upload_time_iso_8601": "2025-07-28T08:39:39.173877Z",
            "url": "https://files.pythonhosted.org/packages/35/7e/a549abe27dd8e696c8dd239b62dd2e18e87a9225a1353802c37c702cf7c6/cipher_solver-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6cbd39bb025690030ff5c9318ab4cef76aea3138d3211e95da7286ce438194bb",
                "md5": "b2e5b020ad3d93811113f42dd75cb42b",
                "sha256": "4c8dcf0ef96fab593394f8965705f4810d938d6a0e6537c2af20251c76781606"
            },
            "downloads": -1,
            "filename": "cipher_solver-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "b2e5b020ad3d93811113f42dd75cb42b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 12017,
            "upload_time": "2025-07-28T08:39:40",
            "upload_time_iso_8601": "2025-07-28T08:39:40.050847Z",
            "url": "https://files.pythonhosted.org/packages/6c/bd/39bb025690030ff5c9318ab4cef76aea3138d3211e95da7286ce438194bb/cipher_solver-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-28 08:39:40",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "alimony",
    "github_project": "cipher_solver",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [
        {
            "name": "numpy",
            "specs": [
                [
                    "==",
                    "2.3.2"
                ]
            ]
        }
    ],
    "lcname": "cipher-solver"
}
        
Elapsed time: 0.80691s