-module(murmur3a). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/murmur3a.gleam"). -export([int_digest/1, bit_array_digest/1, hex_digest/1, hash_string/2, hash_ints/2]). -export_type([hash/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -opaque hash() :: {hash, integer(), integer(), integer()}. -file("src/murmur3a.gleam", 124). ?DOC( " Returns the 32 bit _signed_ integer digest of the hash.\n" "\n" " Keep in mind that these values may return negative numbers!\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " hash_ints([1, 2, 3], 0)\n" " |> int_digest\n" " // -> -2133732860\n" " ```\n" ). -spec int_digest(hash()) -> integer(). int_digest(Hash) -> erlang:element(4, Hash). -file("src/murmur3a.gleam", 137). ?DOC( " Returns 32 bit digest of the hash as a BitArray.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " hash_string(\"murmur3a\", 0)\n" " |> bit_array_digest\n" " // -> <<232, 177, 21, 28>>\n" " ```\n" ). -spec bit_array_digest(hash()) -> bitstring(). bit_array_digest(Hash) -> <<(int_digest(Hash)):32>>. -file("src/murmur3a.gleam", 150). ?DOC( " Returns a hexadecimal digest of the hash.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " hash_string(\"murmur3a\", 0)\n" " |> hex_digest\n" " // -> \"E8B1151C\"\n" " ```\n" ). -spec hex_digest(hash()) -> binary(). hex_digest(Hash) -> _pipe = Hash, _pipe@1 = bit_array_digest(_pipe), gleam_stdlib:base16_encode(_pipe@1). -file("src/murmur3a.gleam", 176). -spec rotate_left(integer(), integer()) -> integer(). rotate_left(N, Shift) -> N@1 = erlang:'band'(N, 16#ffffffff), _pipe = erlang:'bsl'(N@1, Shift), _pipe@1 = erlang:'band'(_pipe, 16#ffffffff), erlang:'bor'(_pipe@1, erlang:'bsr'(N@1, 32 - Shift)). -file("src/murmur3a.gleam", 167). -spec signed_multiply(integer(), integer()) -> integer(). signed_multiply(M, N) -> Result = erlang:'band'(M * N, 16#ffffffff), case Result > 16#7fffffff of true -> Result - 16#100000000; false -> Result end. -file("src/murmur3a.gleam", 70). -spec mix(integer(), integer()) -> integer(). mix(State, Seed) -> _pipe = State, _pipe@1 = signed_multiply(_pipe, 16#cc9e2d51), _pipe@2 = rotate_left(_pipe@1, 15), _pipe@3 = signed_multiply(_pipe@2, 16#1b873593), _pipe@4 = erlang:'bxor'(_pipe@3, Seed), _pipe@5 = rotate_left(_pipe@4, 13), _pipe@6 = signed_multiply(_pipe@5, 5), gleam@int:add(_pipe@6, 16#e6546b64). -file("src/murmur3a.gleam", 57). -spec hash_chunk(hash(), integer()) -> hash(). hash_chunk(Hash, Chunk) -> State = begin _pipe = Chunk, _pipe@1 = erlang:'band'(_pipe, 16#ff), _pipe@2 = erlang:'bsl'(_pipe@1, erlang:element(3, Hash)), erlang:'bor'(_pipe@2, erlang:element(4, Hash)) end, case erlang:element(3, Hash) of 24 -> {hash, mix(State, erlang:element(2, Hash)), 0, 0}; _ -> {hash, erlang:element(2, Hash), erlang:element(3, Hash) + 8, State} end. -file("src/murmur3a.gleam", 81). -spec finalize({hash(), integer()}) -> hash(). finalize(Input) -> {Hash, Length} = Input, State = begin _pipe@5 = case erlang:element(4, Hash) of 0 -> erlang:element(2, Hash); _ -> _pipe = erlang:element(4, Hash), _pipe@1 = signed_multiply(_pipe, 16#cc9e2d51), _pipe@2 = rotate_left(_pipe@1, 15), _pipe@3 = signed_multiply(_pipe@2, 16#1b873593), _pipe@4 = erlang:'bxor'(_pipe@3, erlang:element(2, Hash)), erlang:'band'(_pipe@4, 16#ffffffff) end, erlang:'bxor'(_pipe@5, Length) end, State@1 = begin _pipe@6 = erlang:'bsr'(State, 16), _pipe@7 = erlang:'bxor'(_pipe@6, State), _pipe@8 = signed_multiply(_pipe@7, 16#85ebca6b), erlang:'band'(_pipe@8, 16#ffffffff) end, State@2 = begin _pipe@9 = erlang:'bsr'(State@1, 13), _pipe@10 = erlang:'bxor'(_pipe@9, State@1), signed_multiply(_pipe@10, 16#c2b2ae35) end, {hash, erlang:element(2, Hash), erlang:element(3, Hash), begin _pipe@11 = erlang:'bsr'(State@2, 16), _pipe@12 = erlang:'band'(_pipe@11, 16#ffff), erlang:'bxor'(_pipe@12, State@2) end}. -file("src/murmur3a.gleam", 184). -spec make_fold(fun((LMW) -> integer())) -> fun(({hash(), integer()}, LMW) -> {hash(), integer()}). make_fold(Transform) -> fun(Acc, A) -> {Hash, Length} = Acc, {hash_chunk(Hash, Transform(A)), Length + 1} end. -file("src/murmur3a.gleam", 33). ?DOC( " Computes a 32 bit Murmur3 hash of the input string.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " hash_string(\"murmur3a\", 0)\n" " // -> Hash(3521997819, 0, -391047908)\n" " ```\n" ). -spec hash_string(binary(), integer()) -> hash(). hash_string(Key, Seed) -> _pipe = Key, _pipe@1 = gleam@string:to_utf_codepoints(_pipe), _pipe@2 = gleam@list:fold( _pipe@1, {{hash, Seed, erlang:element(3, {hash, 0, 0, 0}), erlang:element(4, {hash, 0, 0, 0})}, 0}, make_fold(fun gleam_stdlib:identity/1) ), finalize(_pipe@2). -file("src/murmur3a.gleam", 51). ?DOC( " Computes a 32 bit Murmur3 hash of the supplied list of integers.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " hash_ints([1, 2, 3], 0)\n" " // -> Hash(0, 24, -2133732860)\n" " ```\n" ). -spec hash_ints(list(integer()), integer()) -> hash(). hash_ints(Key, Seed) -> _pipe = Key, _pipe@1 = gleam@list:fold( _pipe, {{hash, Seed, erlang:element(3, {hash, 0, 0, 0}), erlang:element(4, {hash, 0, 0, 0})}, 0}, make_fold(fun gleam@function:identity/1) ), finalize(_pipe@1).