-
Notifications
You must be signed in to change notification settings - Fork 0
/
play_fair_matrix.rb
116 lines (105 loc) · 2.42 KB
/
play_fair_matrix.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
require_relative "Alphabet"
class PlayFairMatrix
COLUMNS = 5
attr_reader :matrix
def initialize(options={})
if options[:keyword]
@matrix = build_matrix(keyword: options[:keyword])
else
@matrix = build_matrix
end
end
def char_from_index(options={})
row = options[:row]
column = options[:column]
@matrix[row][column]
end
def chars_matrix_location(options={})
char_array = options[:char_pair].split(//)
char_location = { char1: {row: :p, index: 0, encrypted: '' }, char2: {row: :p, index: 0, encrypted: '' }}
@matrix.each do |key, val_array|
index = 0
val_array.each do |char|
if char_array[0] == char
char_location[:char1][:row] = key
char_location[:char1][:index] = index
end
if char_array[1] == char
char_location[:char2][:row] = key
char_location[:char2][:index] = index
end
index += 1
end
end
char_location
end
def build_matrix(options = {})
if options[:keyword]
build_keyword_matrix(options[:keyword])
else
{A: ['P','L','A','Y','F'],
B: ['R','I','E','X','M'],
C: ['B','C','D','G','H'],
D: ['K','N','O','Q','S'],
E: ['T','U','V','W','Z']}
end
end
def self.previous_row_symbol(options={})
case options[:current_row]
when :A
:E
when :B
:A
when :C
:B
when :D
:C
when :E
:D
end
end
def self.next_row_symbol(options={})
case options[:current_row]
when :A
:B
when :B
:C
when :C
:D
when :D
:E
when :E
:A
end
end
private
def build_keyword_matrix(keyword)
keys = keyword.upcase.gsub(/\s+/,"").split(//).uniq
num_keys = keys.length
current_index = 0
alphabet = Alphabet.new(keyword: keyword)
legal_letters = Alphabet.legal_letters
matrix = {A: [], B: [], C: [], D: [], E: []}
matrix.each do |key, row|
for index in 0..COLUMNS - 1
if current_index < num_keys
matrix[key][index] = keys[current_index]
current_index += 1
else
searching = true
while searching
legal_letters.each do |v_char|
if alphabet.is_char_valid?(v_char)
row[index] = v_char
searching = false
current_index += 1
break
end
end
end
end
end
end
matrix
end
end