-2

In Ruby, I am building a "One Time Pad" Cipher for a project. Although, I already ran into something that I am not familiar with how to do. I need to change a character to an integer and then add an random number.

For the random number, I'll just use rand and then add that to the character. But how do I make the character into an integer that matches the value of that character (A = 1, B = 2, C = 3, etc.). Then how do I add the value of the random number to the character (which has been changed into an integer), and then change the sum of those two back into a character?

Thanks.

HLatfullin
  • 13
  • 2
  • 8
  • 1
    What happened to http://stackoverflow.com/questions/24337461/strings-to-integers? – sawa Jun 21 '14 at 19:39
  • @sawa What happened with vote to close - dupe? – Maarten Bodewes Jun 21 '14 at 21:13
  • Not really, this is to solve a different problem. In this I need to add a random number, this is a "one time pad" cipher whereas the other was more of a Caesar Cipher. – HLatfullin Jun 21 '14 at 21:53
  • 1
    If you have finished with the first question, the following would help people trying to help you: 1) Select a correct answer on first question. 2) Use the knowledge you gained from first question to build on it in the second. Repeating "how do I make the character into an integer" is why this question looks like a duplicate. Some code showing your attempt here would be useful too, so it is clearer where you are stuck, and what the difference between the questions is. If you are not ready to write the second piece of code yet, then slow down a little and learn what you can from the first. – Neil Slater Jun 21 '14 at 22:44
  • Alright, Thanks dude. I will use your instructions as stated above the next time I ask a question on the website. – HLatfullin Jun 22 '14 at 00:11

2 Answers2

0

Try this:

h = {}
v = 0

('A'..'Z').each do |c|
  v+=1
  h[c] = v
end

h will result the hash you are looking for:

{"Z"=>26, "Y"=>25, "X"=>24, "W"=>23, "V"=>22, "U"=>21, "T"=>20, "S"=>19, "R"=>18, "Q"=>17, "P"=>16, "O"=>15, "N"=>14, "M"=>13, "L"=>12, "K"=>11, "J"=>10, "I"=>9, "H"=>8, "G"=>7, "F"=>6, "E"=>5, "D"=>4, "C"=>3, "B"=>2, "A"=>1}

To get a char's respective number, do:

h[char]

Eg. for J you can do: h["J"] to get 10.

Getting the char from integer:

You can get the char from integer using hash#index. Eg.

h.index(22) # => "V"
shivam
  • 16,048
  • 3
  • 56
  • 71
  • Thank you for your answer. I added a random number to that integer, but how do I transform the sum of those two values back into a character? Thanks – HLatfullin Jun 21 '14 at 21:37
  • @DaniyartheKhan you can use #index for that purpose. See my edit – shivam Jun 22 '14 at 06:31
0

Here's an easy and quick way, using String#bytes and Array#pack.

# Get a list of the byte values of each character in a String
b = "Answering".bytes
# => [65, 110, 115, 119, 101, 114, 105, 110, 103]

# Add a random number between 0 and 100 to each integer
r = b.map {|x| x + x.rand(100)}
# => [78, 170, 172, 194, 175, 187, 135, 140, 180]

# Convert it back to a String
scrambled = r.pack('c*')
# => "N\xAA\xAC\xC2\xAF\xBB\x87\x8C\xB4"

Note that Array#pack may run into some trouble (hence the \x... characters) because there aren't enough bits in the normal encoding method to handle the higher byte integers that are created by adding the random number.

There's a more "Ruby" way to do this, which involves Array#each_byte, #map, and a block, but I'll leave that to you to figure out. This one (above) is probably more approachable for those who are used to procedural languages.

acsmith
  • 1,466
  • 11
  • 16