Class: Zola::Crack

Inherits:
Encryptor show all
Defined in:
lib/crack.rb

Instance Attribute Summary collapse

Attributes inherited from Encryptor

#date, #input_file, #key, #keys, #message, #output_file, #processed_message

Instance Method Summary collapse

Methods inherited from Encryptor

#check_message, #generate_key, #generate_keys, #generate_offset, #get_date, #get_key, #process_letter, #process_message, #read_in_message

Constructor Details

#initialize(input_file, output_file) ⇒ Crack

Returns a new instance of Crack.



4
5
6
7
8
9
10
11
# File 'lib/crack.rb', line 4

def initialize(input_file, output_file)
  @known = "..end.."
  @characters =  [*'0'..'9', *'a'..'z',' ','.',","]
  @date = 0
  @number_of_ciphers = 4
  @char_hash = Hash[@characters.map.with_index { |char, i| [char, i] }]
  super(input_file, output_file)
end

Instance Attribute Details

#char_hashObject

Returns the value of attribute char_hash.



3
4
5
# File 'lib/crack.rb', line 3

def char_hash
  @char_hash
end

#knownObject

Returns the value of attribute known.



3
4
5
# File 'lib/crack.rb', line 3

def known
  @known
end

Instance Method Details

#cipher(rotation) ⇒ Object



34
35
36
37
# File 'lib/crack.rb', line 34

def cipher(rotation)
  rotated_characters = @characters.rotate(rotation)
  Hash[rotated_characters.zip(@characters)]
end

#executeObject



12
13
14
15
16
17
# File 'lib/crack.rb', line 12

def execute
  read_in_message
  get_cipher_rotations
  process_message
  output_message
end

#get_cipher_rotationsObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/crack.rb', line 18

def get_cipher_rotations
  # get the index positions of the known keywords letters, and corresponding encrypted keywords letters
  known_indexes = get_indexes(@known)
  encrypted_part = @message[-@known.length, @known.length]
  encrypted_indexes = get_indexes(encrypted_part)
  # subtract the paired indexes to get the number of rotations between the encrypted and unencrypted letters
  rotations = get_rotations(known_indexes, encrypted_indexes)

  # reverse the rotations so that the encrypted letter points to its unencrypted letter
  inverted_rotations = reverse_rotations(rotations)

  # figure out what position each cipher is using
  r = -@message.length % @number_of_ciphers
  @keys = inverted_rotations.rotate(r)
end

#get_indexes(message) ⇒ Object



39
40
41
42
43
# File 'lib/crack.rb', line 39

def get_indexes(message)
  message.each_char.map do |char|
    @char_hash[char]
  end
end

#get_rotations(known, encrypted) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/crack.rb', line 45

def get_rotations(known , encrypted)
  rotations = known.zip(encrypted).map do |i|
                difference = i[0] - i[1]
                # if it takes negative rotations, get the positive counter rotations
                difference = @characters.length + difference if difference < 0
                difference
  end
  rotations.flatten.last(4)
end

#output_messageObject



59
60
61
62
# File 'lib/crack.rb', line 59

def output_message
  File.open(@output_file, "w") { |f| f.write(@processed_message)}
  puts "Created #{@output_file} with ciphers #{@keys}"
end

#reverse_rotations(rotations) ⇒ Object



55
56
57
58
# File 'lib/crack.rb', line 55

def reverse_rotations(rotations)
  len = @characters.length
  rotations.map{ |number| len - number }
end