chaocipher 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gemtest +0 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +47 -0
- data/chaocipher.gemspec +13 -0
- data/lib/chaocipher.rb +29 -0
- data/lib/chaocipher/alphabet.rb +44 -0
- data/lib/chaocipher/cipher.rb +53 -0
- data/rakefile +7 -0
- data/test/test_chaocipher.rb +30 -0
- metadata +74 -0
data/.gemtest
ADDED
File without changes
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
(MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 Adam Prescott
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
ChaoCipher
|
2
|
+
==========
|
3
|
+
|
4
|
+
ChaoCipher is a Ruby implementation of the Chaocipher cipher, invented by J. F. Byrne; the algorithm was disclosed in 2010, hence this small bit of code!
|
5
|
+
|
6
|
+
The Algorithm
|
7
|
+
-------------
|
8
|
+
|
9
|
+
You can find more about the Chaocipher at [Wikipedia/Chaocipher](http://en.wikipedia.org/wiki/Chaocipher), and you can read the [online PDF](http://www.mountainvistasoft.com/chaocipher/ActualChaocipher/Chaocipher-Revealed-Algorithm.pdf) which contains details about the algorithm itself, upon which this code is based. The algorithm isn't that involved and is actually quite rudimentary.
|
10
|
+
|
11
|
+
# How do I use this thing?
|
12
|
+
|
13
|
+
To install from RubyGems:
|
14
|
+
|
15
|
+
gem install chaocipher
|
16
|
+
|
17
|
+
To get the source:
|
18
|
+
|
19
|
+
git clone https://github.com/aprescott/chaocipher.git
|
20
|
+
|
21
|
+
To run the tests with the source:
|
22
|
+
|
23
|
+
rake test
|
24
|
+
|
25
|
+
To contribute:
|
26
|
+
|
27
|
+
* Fork it
|
28
|
+
* Make a new feature branch: `git checkout -b some-new-thing master`
|
29
|
+
* Hack away and add tests
|
30
|
+
* Pull request
|
31
|
+
|
32
|
+
## Basic usage
|
33
|
+
|
34
|
+
The Chaocipher works off two alphabets, a "left" and a "right" alphabet which are used for look-up during ciphering and deciphering. The initial two alphabets are all that is required to have a working cipher. For more details, it's probably best that you just read the PDF linked above.
|
35
|
+
|
36
|
+
require "chaocipher"
|
37
|
+
|
38
|
+
ciphertext_alphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
|
39
|
+
plaintext_alphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
|
40
|
+
|
41
|
+
cipher = ChaoCipher::Cipher.new(ciphertext_alphabet, plaintext_alphabet)
|
42
|
+
|
43
|
+
cipher.encrypt("WELLDONEISBETTERTHANWELLSAID") #=> "OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
|
44
|
+
|
45
|
+
# Cryptographic security
|
46
|
+
|
47
|
+
I have no idea what the strength of this cipher is, so I wouldn't encrypt anything of utter importance with it, personally.
|
data/chaocipher.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "chaocipher"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.authors = ["Adam Prescott"]
|
5
|
+
s.email = ["adam@aprescott.com"]
|
6
|
+
s.homepage = "https://github.com/aprescott/chaocipher"
|
7
|
+
s.summary = "A Ruby implementation of the Chaocipher cipher."
|
8
|
+
s.description = "ChaoCipher is a Ruby implementation of the Chaocipher cipher, invented by J. F. Byrne; the algorithm was disclosed in 2010."
|
9
|
+
s.files = Dir["{lib/**/*,test/**/*}"] + %w[LICENSE Gemfile rakefile README.md chaocipher.gemspec .gemtest]
|
10
|
+
s.require_path = "lib"
|
11
|
+
s.test_files = Dir["test/*"]
|
12
|
+
s.add_development_dependency "rake"
|
13
|
+
end
|
data/lib/chaocipher.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2010 Adam Prescott
|
2
|
+
# Licensed under the MIT license. See LICENSE.
|
3
|
+
|
4
|
+
# Ruby 1.8
|
5
|
+
unless Array.new.respond_to?(:rotate)
|
6
|
+
class Array
|
7
|
+
def rotate(n = 1)
|
8
|
+
rotate_amount = n % size
|
9
|
+
return self if rotate_amount < 1 # will be true if n < 1 or size < 2
|
10
|
+
self[rotate_amount..-1] + self[0..rotate_amount-1]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ChaoCipher
|
16
|
+
ZENITH_INDEX = 0
|
17
|
+
NADIR_INDEX = 13
|
18
|
+
ZENITH_POSITION = ZENITH_INDEX + 1
|
19
|
+
NADIR_POSITION = NADIR_INDEX + 1
|
20
|
+
|
21
|
+
VERSION_TINY = 1
|
22
|
+
VERSION_MINOR = 0
|
23
|
+
VERSION_MAJOR = 0
|
24
|
+
|
25
|
+
VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_TINY].join(".")
|
26
|
+
end
|
27
|
+
|
28
|
+
require "chaocipher/alphabet"
|
29
|
+
require "chaocipher/cipher"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ChaoCipher
|
2
|
+
class Alphabet
|
3
|
+
attr_reader :characters, :type
|
4
|
+
|
5
|
+
def initialize(characters, kind)
|
6
|
+
@type = kind
|
7
|
+
@characters = characters
|
8
|
+
raise(ArgumentError, "given alphabet is not a permutation of A-Z") unless self.class.valid?(@characters)
|
9
|
+
end
|
10
|
+
|
11
|
+
def zenith
|
12
|
+
@characters.first
|
13
|
+
end
|
14
|
+
|
15
|
+
def nadir
|
16
|
+
@characters[NADIR_INDEX]
|
17
|
+
end
|
18
|
+
|
19
|
+
def permute(new_zenith)
|
20
|
+
self.class.permute(@characters, new_zenith, type)
|
21
|
+
end
|
22
|
+
|
23
|
+
def permute!(new_zenith)
|
24
|
+
@characters.replace(permute(new_zenith))
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.permute(characters, new_zenith, type)
|
28
|
+
if type == :ciphertext
|
29
|
+
amount_to_skip = 1
|
30
|
+
else
|
31
|
+
amount_to_skip = 2
|
32
|
+
end
|
33
|
+
|
34
|
+
permuted_characters = characters.rotate(characters.index(new_zenith))
|
35
|
+
permuted_characters = permuted_characters.rotate unless type == :ciphertext
|
36
|
+
|
37
|
+
permuted_characters[0..amount_to_skip-1] + permuted_characters[amount_to_skip..NADIR_INDEX].rotate + permuted_characters[NADIR_INDEX+1..-1]
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.valid?(characters)
|
41
|
+
characters.sort.join("") =~ /[a-z]/i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ChaoCipher
|
2
|
+
class Cipher
|
3
|
+
def initialize(ciphertext_alphabet, plaintext_alphabet)
|
4
|
+
@original_ciphertext_alphabet = ciphertext_alphabet
|
5
|
+
@original_plaintext_alphabet = plaintext_alphabet
|
6
|
+
@ciphertext_alphabet = Alphabet.new(ciphertext_alphabet.upcase.chars.to_a, :ciphertext)
|
7
|
+
@plaintext_alphabet = Alphabet.new(plaintext_alphabet.upcase.chars.to_a, :plaintext)
|
8
|
+
end
|
9
|
+
|
10
|
+
def reinitialize!
|
11
|
+
@ciphertext_alphabet = Alphabet.new(@original_ciphertext_alphabet.upcase.chars.to_a, :ciphertext)
|
12
|
+
@plaintext_alphabet = Alphabet.new(@original_plaintext_alphabet.upcase.chars.to_a, :plaintext)
|
13
|
+
end
|
14
|
+
|
15
|
+
def plaintext_letter_for(ciphertext_letter)
|
16
|
+
@plaintext_alphabet.characters[@ciphertext_alphabet.characters.index(ciphertext_letter)]
|
17
|
+
end
|
18
|
+
|
19
|
+
def ciphertext_letter_for(plaintext_letter)
|
20
|
+
@ciphertext_alphabet.characters[@plaintext_alphabet.characters.index(plaintext_letter)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def cipher(mode, text)
|
24
|
+
reinitialize!
|
25
|
+
|
26
|
+
converted_text = ""
|
27
|
+
|
28
|
+
text.chars.each do |character|
|
29
|
+
if mode == :encrypt
|
30
|
+
@last_converted_letter = ciphertext_letter_for(character)
|
31
|
+
@ciphertext_alphabet.permute!(@last_converted_letter)
|
32
|
+
@plaintext_alphabet.permute!(character)
|
33
|
+
else
|
34
|
+
@last_converted_letter = plaintext_letter_for(character)
|
35
|
+
@ciphertext_alphabet.permute!(character)
|
36
|
+
@plaintext_alphabet.permute!(@last_converted_letter)
|
37
|
+
end
|
38
|
+
|
39
|
+
converted_text << @last_converted_letter
|
40
|
+
end
|
41
|
+
|
42
|
+
converted_text
|
43
|
+
end
|
44
|
+
|
45
|
+
def encrypt(plaintext)
|
46
|
+
cipher(:encrypt, plaintext)
|
47
|
+
end
|
48
|
+
|
49
|
+
def decrypt(ciphertext)
|
50
|
+
cipher(:decrypt, ciphertext)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require "chaocipher"
|
4
|
+
|
5
|
+
class TestChaoCipher < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
ciphertext_alphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
|
8
|
+
plaintext_alphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
|
9
|
+
@cipher = ChaoCipher::Cipher.new(ciphertext_alphabet, plaintext_alphabet)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_encryption
|
13
|
+
assert_equal "OAHQHCNYNXTSZJRRHJBYHQKSOUJY", @cipher.encrypt("WELLDONEISBETTERTHANWELLSAID")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_decryption
|
17
|
+
assert_equal "WELLDONEISBETTERTHANWELLSAID", @cipher.decrypt("OAHQHCNYNXTSZJRRHJBYHQKSOUJY")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_reversible
|
21
|
+
ciphertext_alphabet = ("A".."Z").to_a.shuffle.join("")
|
22
|
+
plaintext_alphabet = ("A".."Z").to_a.shuffle.join("")
|
23
|
+
|
24
|
+
cipher = ChaoCipher::Cipher.new(ciphertext_alphabet, plaintext_alphabet)
|
25
|
+
|
26
|
+
str = ("A".."Z").to_a.shuffle.join("")
|
27
|
+
|
28
|
+
assert_equal str, cipher.decrypt(cipher.encrypt(str))
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chaocipher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Prescott
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-19 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
description: ChaoCipher is a Ruby implementation of the Chaocipher cipher, invented by J. F. Byrne; the algorithm was disclosed in 2010.
|
27
|
+
email:
|
28
|
+
- adam@aprescott.com
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- lib/chaocipher/alphabet.rb
|
37
|
+
- lib/chaocipher/cipher.rb
|
38
|
+
- lib/chaocipher.rb
|
39
|
+
- test/test_chaocipher.rb
|
40
|
+
- LICENSE
|
41
|
+
- Gemfile
|
42
|
+
- rakefile
|
43
|
+
- README.md
|
44
|
+
- chaocipher.gemspec
|
45
|
+
- .gemtest
|
46
|
+
homepage: https://github.com/aprescott/chaocipher
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.8.2
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: A Ruby implementation of the Chaocipher cipher.
|
73
|
+
test_files:
|
74
|
+
- test/test_chaocipher.rb
|