# How to get the codepoint of a variable?

Hello Elixir community,

in order to implement a cipher for a code challenge I have to add the integer representation of each key in the message and the key among other things. The integer representation: `A` becomes `1`, `B` becomes `2` etc. We can ignore the offset in ASCII for now.

``````msg: ABC = 1,2,3
key: DEF = 4,5,6

=> 1+4, 2+5, 3+6
=> 5,7,9
``````

I tried to create a function that adds the codepoints of two chars a and b:

``````def combine(a, b), do: ?a + ?b
``````

The problem is that the codepoints of the letters a and b are added, not the parameter’s codepoints. Hence I’m always adding `97 + 98`, regardless which chars I passed to `combine`.

Is there an alternative way to get the code point of a parameter/variable?

Hmm, why not just:

``````def combine(a, b), do: a + b
``````

Or what are you trying to accomplish?

For note, `?x` is just the ASCII value of `x`, the actual letter, it has nothing to do with any binding that may be named that way as well.

Hello @OvermindDL1,

I’m trying to implement the Solitaire cipher. For this I have a message and a key of the same length which only contain uppercased letters of the latin alphabet.

In the next step I have to add the numerical representations (e.g. `A` being `1` in the alphabet or `65` in ASCII) of each letter in the message and the key. The result is the encrypted message.

I wrote a `zipWith` helper function (borrowed from Haskell) to add the letters of the key and message:

``````zipWith(msg, key, &combiner/2)
``````

As you already saw in the implementation of the `combiner` method it takes two letters and adds their numerical representation.

The point where I’m struggling is that I can’t get the ASCII code for the letters in order to add them.

@digitalcraftsman: How about using `charlist`?

You should know that:

``````'abc' == [97, 98, 99]
``````

So you will have:

``````msg = 'abc'
key = 'def`
``````

Then you can use `&Enum.with_index/1`.
Finally you can use `&Enum.map/1` on one of them.
Example:

``````defmodule Example do
def sample(msg, key) do
msg_with_index = Enum.with_index(msg)
key_with_index = Enum.with_index(key)
IO.puts "message codepoints: " <> inspect(msg, charlists: :as_lists)
IO.puts "key codepoints: " <> inspect(key, charlists: :as_lists)
Enum.map(msg_with_index, &combine(&1, key_with_index))
end

defp combine({msg, index}, key_with_index) do
{key, _} = Enum.find(key_with_index, fn {_, index2} -> index == index2 end)
IO.puts "#{msg} + #{key} = #{msg + key}"
msg + key
end
end
``````

Finally run them like:

``````msg = 'abc'
key = 'def'
Example.sample(msg, key)
``````

or:

``````msg = [1, 2, 3]
key = [4, 5, 6]
Example.sample(msg, key)
``````

or:

``````msg_string = "abc"
key_string = "def"
msg = String.to_charlist(msg_string)
key = String.to_charlist(key_string)
Example.sample(msg, key)
``````
2 Likes

Hello @Eiji,

thank you for sharing your ideas and posting the detailed code examples At the beginning I might have thought to complex about the problem with the goal to reduce the number of list operations. However, with your appraoch and some inspiration from the submitted solutions of RubyQuiz #1 I came up with the following:

Feel free to suggest improvements.

``````defmodule SolitaireCipher do
def encrypt(msg, key) do
process(msg, key, fn(m, k) -> 64 + mod(m + k - 128) end)
end

def decrypt(msg, key) do
process(msg, key, fn(m, k) -> 64 + mod(m - k) end)
end

defp process(msg, key, routine) do
msg
|> prepare
|> Enum.map(fn(msg_p) -> combine(prepare(key), msg_p, routine) end)
|> List.to_string
end

defp prepare(input) do
input
|> String.upcase
|> String.replace(~r/[^A-Z]/, "")
|> String.to_charlist
|> Enum.with_index
end

defp combine(key_with_index, {m, m_index}, routine) do
{k, _} = Enum.find(key_with_index, fn({_, k_index}) -> m_index == k_index end)
routine.(m, k)
end

defp mod(char) when char > 26, do: char-26
defp mod(char) when char <  1, do: char+26
defp mod(char), do: char
end
``````

And if someone wants to try the example from the quiz:

``````msg = "Code in Ruby, live longer!"
key = "DWJXHYRFDGTMSHPUURXJ"

SolitaireCipher.encrypt(msg, key)
|> SolitaireCipher.decrypt(key)
``````

@digitalcraftsman: if it works as expected (decrypted message is not same as original) then it’s ok
I’m not expert of speed optimisations and cryptography, so if there is something to suggest then I see only indention and documentation + type validation.
Please use `2 spaces` for indention (at least when sharing code in forum - simple replace) - I think that comparing this my code looks better Example:

``````defmodule SolitaireCipher do
@moduledoc """
Solitare Cipher
( ... )

Usage:

iex> msg = "Code in Ruby, live longer!"
"Code in Ruby, live longer!"
iex> key = "DWJXHYRFDGTMSHPUURXJ"
"DWJXHYRFDGTMSHPUURXJ"
iex> msg |> SolitaireCipher.encrypt(key) |> SolitaireCipher.decrypt(key)
"CODEINRUBYLIVELONGER"
"""

@spec encrypt(String.t, String.t) :: String.t
@doc """
Encrypting message.

This function requires two parameters:
`msg` - message to encrypt
`key` - key for encryption and decryption process
"""
def encrypt(msg, key) when is_bitstring(msg) and is_bitstring(key) do
# ...
end

# and similarly for decrypt method
# ...

end
``````

Well, the message that the types in is sanitized before the encryption starts. This process removes everything that isn’t a letter of the latin alphabet and uppercases the remaining letters. Hence you actually encrypt “CODEINRUBYLIVELONGER” according to the exercise.

This was just a fun exercise so that I’ve a reason to get more familiar with the standard library. The cryptographic aspect can be omitted. I was more talking about reducing operations on the strings and char lists.

Please use 2 spaces for indention (at least when sharing code in forum - simple replace) - I think that comparing this my code looks better

I’ll fix the indentation in the code example above. Regarding documentation I’ll look into this as well. Currently, I’m half way through Elixir in Action and there still a ton of stuff left to learn.