I am trying to write a simple module that prepares a valid URL link. The URL needs a checksum param passed. The checksum calculations is very simple: concat all the values of the passed params(key + value) add salt and hash it.
Here is the sample* code(lets ignore for the moment that I need some kind of ordered map, cause there is no guarantee that the map is iterated in the same order. ScRequest is a struct containing the secret_key and the hashish algorithm):
defp calculate_v4_checksum(sc_request, params) do
# this fails: str_to_hash = Enum.map(params, fn {k, v} -> Atom.to_string(k) <> v end) <> sc_request.secret_key
str_to_hash = Enum.map(params, fn {k, v} -> Atom.to_string(k) <> v end)
IO.puts (str_to_hash)
IO.puts (sc_request.secret_key)
# this fails: IO.puts (str_to_hash <> sc_request.secret_key)
# or this: :crypto.hash(sc_request.algorithm, str_to_hash <> sc_request.secret_key)
:crypto.hash(sc_request.algorithm, str_to_hash)
|> Base.encode16(case: :lower)
end
Why the concatenation of the salt(secret_key) fails with ArgumentError ? Currently I can only hash the concatenated params…
As I already said in my first answer, Enum.map returns a list, due to the function you passed into it, that was a list of String.t, but a list of strings is not a string. <> does really only work for binaries (and therefore for strings as well).