mirror of
https://github.com/Smaug123/ClassicalCiphers.jl
synced 2025-10-05 09:28:44 +00:00
Enforce lower/uppercase consistency; expand readme
This commit is contained in:
42
README.md
42
README.md
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.org/Smaug123/ClassicalCiphers.jl)
|
||||
|
||||
# ClassicalCiphers
|
||||
|
||||
## Main Features
|
||||
@@ -12,9 +14,45 @@ The Solitaire cipher is included for completeness, though it is perhaps not stri
|
||||
* [Vigenère]
|
||||
* [Solitaire]
|
||||
|
||||
## Gotchas
|
||||
|
||||
In general, `encrypt` functions turn text upper-case, while `decrypt` functions
|
||||
turn text lower-case.
|
||||
This is consistent with convention, but may not be expected.
|
||||
|
||||
## Code samples
|
||||
|
||||
### Caesar cipher
|
||||
|
||||
Encrypt the text "Hello, World!" with a Caesar offset of 3 (that is, sending
|
||||
'a' to 'd'):
|
||||
```julia
|
||||
encrypt_caesar("Hello, World!", 3)
|
||||
# outputs "khoor, zruog!"
|
||||
```
|
||||
|
||||
Notice that `encrypt_caesar` turns everything upper-case, but retains symbols.
|
||||
|
||||
Decrypt the same text:
|
||||
```julia
|
||||
decrypt_caesar("Khoor, Zruog!", 3)
|
||||
# outputs "hello, world!"
|
||||
```
|
||||
|
||||
Likewise, `decrypt_caesar` turns everything lower-case, but retains symbols.
|
||||
|
||||
### Monoalphabetic cipher
|
||||
|
||||
Encrypt the text "Hello, World!" with the same Caesar cipher, but
|
||||
viewed as a monoalphabetic substitution:
|
||||
|
||||
```julia
|
||||
encrypt_monoalphabetic("Hello, World!", "DEFGHIJKLMNOPQRSTUVWXYZABC")
|
||||
# outputs "KHOOR, ZRUOG!"
|
||||
```
|
||||
|
||||
|
||||
[Caesar]: https://en.wikipedia.org/wiki/Caesar_cipher
|
||||
[Vigenère]: https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
|
||||
[Monoalphabetic substitution]: https://en.wikipedia.org/wiki/Substitution_cipher
|
||||
[Solitaire]: https://en.wikipedia.org/wiki/Solitaire_(cipher)
|
||||
|
||||
[](https://travis-ci.org/Smaug123/ClassicalCiphers.jl)
|
||||
|
@@ -1,14 +1,15 @@
|
||||
"""
|
||||
Encrypts the given plaintext according to the Caesar cipher.
|
||||
The key is given as an integer, being the offset of each character;
|
||||
so encrypt_caesar("abc", 1) == "bcd".
|
||||
so encrypt_caesar("abc", 1) == "BCD".
|
||||
|
||||
Converts the input to lowercase.
|
||||
Converts the input to uppercase.
|
||||
"""
|
||||
function encrypt_caesar(plaintext, key::Integer)
|
||||
# plaintext: string; key: integer offset, so k=1 sends "a" to "b"
|
||||
key = ((key-1) % 26) + 1
|
||||
encrypt_monoalphabetic(plaintext, join([collect(Char(97+key):'z'); collect('a':Char(97+key-1))]))
|
||||
keystr = join([collect(Char(97+key):'z'); collect('a':Char(97+key-1))])
|
||||
encrypt_monoalphabetic(plaintext, keystr)
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -19,7 +20,7 @@ so decrypt_caesar("abcd", 1) == "zabc".
|
||||
Converts the input to lowercase.
|
||||
"""
|
||||
function decrypt_caesar(ciphertext, key::Integer)
|
||||
# ciphertext: string; key: integer offset, so k=1 decrypts "B" as "A"
|
||||
# ciphertext: string; key: integer offset, so k=1 decrypts "B" as "a"
|
||||
key = ((key-1) % 26) + 1
|
||||
encrypt_caesar(ciphertext, 26-key)
|
||||
lowercase(encrypt_caesar(ciphertext, 26-key))
|
||||
end
|
||||
|
@@ -35,9 +35,8 @@ end
|
||||
function encrypt_monoalphabetic(plaintext, key::AbstractString)
|
||||
# plaintext: string; key: string of length 26, first character is the image of 'a', etc
|
||||
# working in lowercase; key is assumed only to have each element appearing once
|
||||
# and to be in lowercase.
|
||||
dict = Dict{Char, Char}(map(x -> (x[1]+96, x[2]), enumerate(key)))
|
||||
encrypt_monoalphabetic(lowercase(plaintext), dict)
|
||||
dict = Dict{Char, Char}(map(x -> (x[1]+64, x[2]), enumerate(uppercase(key))))
|
||||
encrypt_monoalphabetic(uppercase(plaintext), dict)
|
||||
end
|
||||
|
||||
function decrypt_monoalphabetic(ciphertext, key::AbstractString)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Encrypts the given string using the Vigenere cipher according to the given vector of offsets.
|
||||
For example, encrypt_vigenere("ab", [0, 1]) returns "ac".
|
||||
For example, encrypt_vigenere("ab", [0, 1]) returns "AC".
|
||||
"""
|
||||
function encrypt_vigenere(plaintext, key::Array)
|
||||
# plaintext: string; key: vector of integer offsets, so [0, 1] encrypts "ab" as "ac"
|
||||
@@ -16,16 +16,15 @@ For example, decrypt_vigenere("ac", [0, 1]) returns "ab".
|
||||
"""
|
||||
function decrypt_vigenere(ciphertext, key::Array)
|
||||
# ciphertext: string; key: vector of integer offsets, so [0, 1] decrypts "ac" as "ab"
|
||||
encrypt_vigenere(ciphertext, 26-key)
|
||||
lowercase(encrypt_vigenere(ciphertext, 26-key))
|
||||
end
|
||||
|
||||
"""
|
||||
Encrypts the given string using the Vigenere cipher according to the given keystring.
|
||||
For example, encrypt_vigenere("ab", "ab") returns "ac".
|
||||
For example, encrypt_vigenere("ab", "ab") returns "AC".
|
||||
"""
|
||||
function encrypt_vigenere(ciphertext, key::AbstractString)
|
||||
# ciphertext: string; key: string, so "ab" encrypts "ab" as "ac"
|
||||
|
||||
# ciphertext: string; key: string, so "ab" encrypts "ab" as "AC"
|
||||
encrypt_vigenere(ciphertext, [Int(i)-97 for i in lowercase(letters_only(key))])
|
||||
end
|
||||
|
||||
@@ -36,4 +35,4 @@ For example, decrypt_vigenere("ab", "ac") returns "ab".
|
||||
function decrypt_vigenere(plaintext, key::AbstractString)
|
||||
# plaintext: string; key: string, so "ab" decrypts "ac" as "ab"
|
||||
decrypt_vigenere(plaintext, [Int(i)-97 for i in lowercase(letters_only(key))])
|
||||
end
|
||||
end
|
||||
|
@@ -10,6 +10,6 @@ using Base.Test
|
||||
|
||||
@test decrypt_monoalphabetic("WKLV FRGH ZDV LQYHQWHG EB MXOLXV FDHVDU", "DEFGHIJKLMNOPQRSTUVWXYZABC") == lowercase("THIS CODE WAS INVENTED BY JULIUS CAESAR")
|
||||
|
||||
@test encrypt_caesar("THIS CODE WAS INVENTED BY JULIUS CAESAR", 3) == lowercase("WKLV FRGH ZDV LQYHQWHG EB MXOLXV FDHVDU")
|
||||
@test encrypt_caesar("THIS CODE WAS INVENTED BY JULIUS CAESAR", 3) == "WKLV FRGH ZDV LQYHQWHG EB MXOLXV FDHVDU"
|
||||
|
||||
@test decrypt_caesar("WKLV FRGH ZDV LQYHQWHG EB MXOLXV FDHVDU", 3) == lowercase("THIS CODE WAS INVENTED BY JULIUS CAESAR")
|
||||
|
@@ -1,18 +1,18 @@
|
||||
using ClassicalCiphers
|
||||
using Base.Test
|
||||
|
||||
@test encrypt_solitaire("aaaaaaaaaaaaaaa", "") == lowercase("EXKYIZSGEHUNTIQ")
|
||||
@test encrypt_solitaire("aaaaaaaaaaaaaaa", "f") == lowercase("XYIUQBMHKKJBEGY")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "fo") == lowercase("TUJYMBERLGXNDIW")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "foo") == lowercase("ITHZUJIWGRFARMW")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "a") == lowercase("XODALGSCULIQNSC")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "aa") == lowercase("OHGWMXXCAIMCIQP")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "aaa") == lowercase("DCSQYHBQZNGDRUT")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "b") == lowercase("XQEEMOITLZVDSQS")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "bc") == lowercase("QNGRKQIHCLGWSCE")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "bcd") == lowercase("FMUBYBMAXHNQXCJ")
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAAAAAAAAAAAA", "cryptonomicon") == lowercase("SUGSRSXSWQRMXOHIPBFPXARYQ")
|
||||
@test encrypt_solitaire("SOLITAIREX", "cryptonomicon") == lowercase("KIRAKSFJAN")
|
||||
@test encrypt_solitaire("aaaaaaaaaaaaaaa", "") == "EXKYIZSGEHUNTIQ"
|
||||
@test encrypt_solitaire("aaaaaaaaaaaaaaa", "f") == "XYIUQBMHKKJBEGY"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "fo") == "TUJYMBERLGXNDIW"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "foo") == "ITHZUJIWGRFARMW"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "a") == "XODALGSCULIQNSC"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "aa") == "OHGWMXXCAIMCIQP"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "aaa") == "DCSQYHBQZNGDRUT"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "b") == "XQEEMOITLZVDSQS"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "bc") == "QNGRKQIHCLGWSCE"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAA", "bcd") == "FMUBYBMAXHNQXCJ"
|
||||
@test encrypt_solitaire("AAAAAAAAAAAAAAAAAAAAAAAAA", "cryptonomicon") == "SUGSRSXSWQRMXOHIPBFPXARYQ"
|
||||
@test encrypt_solitaire("SOLITAIREX", "cryptonomicon") == "KIRAKSFJAN"
|
||||
|
||||
@test decrypt_solitaire("EXKYI ZSGEH UNTIQ", "") == "aaaaaaaaaaaaaaa"
|
||||
@test decrypt_solitaire("XYIUQ BMHKK JBEGY ", "f") == "aaaaaaaaaaaaaaa"
|
||||
|
@@ -2,16 +2,15 @@ using ClassicalCiphers
|
||||
using Base.Test
|
||||
|
||||
# doc examples
|
||||
@test encrypt_vigenere("ab", [0, 1]) == "ac"
|
||||
@test encrypt_vigenere("ab", [0, 1]) == "AC"
|
||||
@test decrypt_vigenere("ac", [0, 1]) == "ab"
|
||||
@test encrypt_vigenere("ab", "ab") == "ac"
|
||||
@test encrypt_vigenere("ab", "ab") == "AC"
|
||||
@test decrypt_vigenere("ac", "ab") == "ab"
|
||||
|
||||
# others
|
||||
|
||||
@test decrypt_vigenere("DYIMXMESTEZDPNFVVAMJ", [11, 18, 5, 13, 12, 9, 14]-1) == lowercase("THEAMERICANSHAVEROBB")
|
||||
@test decrypt_vigenere("DYIMXMESTEZDPNFVVAMJ", [11, 18, 5, 13, 12, 9, 14]-1) == "theamericanshaverobb"
|
||||
|
||||
@test decrypt_vigenere("DYIMXMESTEZDPNFVVAMJ", "kremlin") == lowercase("THEAMERICANSHAVEROBB")
|
||||
@test decrypt_vigenere("DYIMXMESTEZDPNFVVAMJ", "kremlin") == "theamericanshaverobb"
|
||||
|
||||
@test encrypt_vigenere("THEAMERICANSHAVEROBB", "kremlin") ==
|
||||
lowercase("DYIMXMESTEZDPNFVVAMJ")
|
||||
@test encrypt_vigenere("THEAMERICANSHAVEROBB", "kremlin") == "DYIMXMESTEZDPNFVVAMJ"
|
||||
|
Reference in New Issue
Block a user