0

I have created this silly cipher but I can't get it to work properly..

Let's say i type a single letter "h" and let the script do it's work.

I've created a method which counts the length of an string (in this case hash value) minus a the value of another string (in this case 100). Then the script should create a new string based on whatever 100 minus the hash value length is (as seen below).

When I print the cipher plus the random string (which together creates a "encrypted message"), they don't add up to 100. I think I got like 41 characters. So what's going on here? Why doesn't it work? And how to I solve it?

    ####
    # Counts the characters of the encrypted message and returns 
    # the number of characters that needs to be generated and added
    # to the message so that every encrypted message has a total
    # of 100 characters.
    def add_random_fill(string)
    char_length = 100 - string.size  
    return ([*('0'..'9'),*('a'..'z')]).sample(char_length.to_i).join
    end

cipher = {
   "a" => ['1q24t', 'akO17'],    
   "b" => ['5T15q', 'x1m45'],
   "c" => ['1p97x', '9zP23'],   
   "d" => ['9z22z', '7qM61'],   
   "e" => ['1r18i', '5ik80'],
   "f" => ['3P42e', '9tv12'],
   "g" => ['7j80e', '13y25'],
   "h" => ['1k51w', 'u6c74'], 
   "i" => ['6c85c', 'gT399'],
   "j" => ['9V36v', 'z1P58'],
   "k" => ['3L88j', '0hi92'],
   "l" => ['6j11o', 'e7r33'], 
   "m" => ['1b82y', 'j1k26'],
   "n" => ['2y43e', 'kXO91'],
   "o" => ['7h48q', 'W1e12'],
   "p" => ['1Z10p', 'M9y53'],
   "q" => ['9B32o', '5sf48'],
   "r" => ['7W77l', 'n3n27'],
   "s" => ['3s43k', '20l85'],
   "t" => ['7cY5b', '88o93'],
   "u" => ['8i14n', '0Ri04'],
   "v" => ['9R81s', '4a118'],
   "w" => ['1q43a', 'tU081'],
   "x" => ["1a02s", "pA323"],
   "y" => ["9o00e", "i8j35"], 
   "z" => ["1j69y", "D7x91"]
   }

prompt = ">> "
puts "Enter a message you would like to encrypt.", prompt
input = gets.chomp
encrypted_content = input.gsub(Regexp.union( cipher.keys ))  { |m| cipher[m].sample }
output = encrypted_content + add_random_fill(encrypted_content)


puts "\n****************************************************************" 
puts "Encrypted message: #{output}"
puts "******************************************************************"
  • Can you narrow down you query, It is difficult in the whole code and understanding the whole problem. – Saurabh Apr 14 '15 at 12:40

1 Answers1

2

Why doesn't it work?

Your "random" array contains 36 elements:

array = [*('0'..'9'),*('a'..'z')] #=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

array.size #=> 36

sample doesn't return more than that:

array.sample(100).size #=> 36

And how to I solve it?

You could use a loop instead, fetching one random element at a time:

char_length.times.map { array.sample }.join

# or 

Array.new(char_length) { array.sample }.join
Stefan
  • 109,145
  • 14
  • 143
  • 218