MatijaL

MatijaL

Hi,
I’m trying to hash a random number but can’t make it work…

num = Enum.random(1..9999)
hashed_num = :crypto.hash(:sha256, num)

I’m getting “1st argument: not an iodata term” error. From my understanding, Enum.random creates a number and :crypto.hash wants an iodata. The same thing happens if I use :crypto.rand_uniform(1, 9999) instead of Enum.random… can anyone help?

Showing Posts 1 to 10

soup

soup

You have to convert the integer to a bitstring then :crypto.hash will accept it:

num = 999
width_in_bits = 64 # unsure if it's possible to get this dynamically?
bin = <<num::integer-size(width_in_bits)>>
hashed_num = :crypto.hash(:sha256, bin)
{num, bin, hashed_num}

Someone clever can let us know if it’s possible to get the bit width of an number dynamically. I’ve only ever used this with fixed/known widths. You could just wing it on a huge width if you didn’t really care. AFAIK beam numbers have no maximum value, so no maximum width but you can generally scope your usecase.

LostKobrakai

LostKobrakai

An integer() value is not a subtype of iodata() and even the integers allowed as part of an iolist need to be byte values, so in the range of 0..255. you likely want to encode your integer to a binary format first.

MatijaL

MatijaL OP

num = 
    Enum.random(1..999) 
    |> Integer.to_string()

hashed_num = :crypto.hash(:sha256, num)

This is the final code for future reference, converting integer to string as @LostKobrakai suggested was all that was needed.

tangui

tangui

You can transform any term to a binary (and then hash it) with :erlang.binary_to_term/1:

iex> :erlang.term_to_binary(42)
<<131, 97, 42>>
iex> :erlang.term_to_binary(42.0)
<<131, 70, 64, 69, 0, 0, 0, 0, 0, 0>>
iex> :erlang.term_to_binary({4, 2})
<<131, 104, 2, 97, 4, 97, 2>>
soup

soup

Note that’s hashing the string “999”, not the integer 999, which might make a difference to some intentions or across application contexts. (You could argue that settling on “we always hash everything as utf8-string” as being more transportable/less-complex?)

Your hashing here is fixed width but for some things like encoding Base58 it makes a difference in payload size if nothing else.

t = DateTime.utc_now() |> DateTime.to_unix(:microsecond)

to_string_encode =
  t
  |> Integer.to_string()
  |> Base.encode64()
  |> dbg()

to_bin_encode =
  t
  |> then(fn x ->
    <<x::unsigned-integer-size(64)>>
  end)
  |> Base.encode64()
  |> dbg()

to_string_base =
  t
  # you can also pass a 2->36 (not 64!) as a base
  # this is *not* functionally the same thing though!
  |> Integer.to_string(32)
  |> dbg()

[
  to_string_encode: to_string_encode,
  to_bin_encode: to_bin_encode,
]

# the encoded string is a larger payload than the encoded integer
# => [to_string_encode: "MTY2NjQzNTI4MTAzNzU3NA==",
# =>  to_bin_encode:    "AAXrnTL3qQY="]

term_to_binary might be problematic as its leading byte is a version number (which I assume can change …) and the docs warn “There is no guarantee that this function will return the same encoded representation for the same term.”

There is an option for deterministic but it’s not x-otp version stable.

Option deterministic (introduced in OTP 24.1) can be used to ensure that within the same major release of Erlang/OTP, the same encoded representation is returned for the same term. There is still no guarantee that the encoded representation remains the same between major releases of Erlang/OTP.

That does make me wonder though, how easy is it to safely & stabley hash an actual composed data type? You could convert to some other format like json or mpack but those aren’t guaranteed to be stably ordered. I guess you’re stuck converting each value to a bitstring/hash and hashing the combination?

dimitarvp

dimitarvp

Not text string. People are telling you to convert your integer to a bit string.

MatijaL

MatijaL OP

Is this the right way?

Enum.random(1..999)
|> Integer.to_string()
|> Base.encode64()
dimitarvp

dimitarvp

No, you’re still producing a text string. You were pointed at several other ways above.

Sebb

Sebb

1..9999 |> Enum.map(&(&1 |> :math.log2() |> ceil)) 
soup

soup

Smarter than max_n |> Integer.to_string(2) |> String.length() :smile:

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
psy-q
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews