   # alias both SipHash.State/Util
   alias SipHash.State, as: State
   alias SipHash.Util, as: Utils
-
-  # define the (constant) grouping pattern
-  @eighth_group_regex ~r/.{1,8}/
 
   @doc """
   Based on the algorithm as described in https://131002.net/siphash/siphash.pdf,

      raise "Key must be exactly 16 bytes."
    end

    length = byte_size(input)
    remain = rem(length, 8)
    s_case = Keyword.get(opts, :case, :upper)
    c_pass = Keyword.get(opts, :c, 2)
    d_pass = Keyword.get(opts, :d, 4)
    l_pad  = Keyword.get(opts, :padding, false)
    state  = State.initialize(key)
    chunks = Regex.scan(@eighth_group_regex, input)
    last_m = Utils.apply_mask64(length <<< 56)

    state =
      chunks
      |> Stream.map(&List.first/1)
      |> Stream.take_while(&(byte_size(&1) == 8))
      |> Enum.reduce(state, (&State.apply_block(&2, &1, c_pass)))

    if remain > 0 do
      { _, last_m } =
        chunks
        |> List.last
        |> List.first
        |> String.reverse
        |> String.codepoints
        |> Enum.reduce({ remain, last_m }, fn(point, acc) ->
            { index, last_m } = acc

            next_index  = index - 1
            point_bytes = Utils.bytes_to_long(point)

            right_side =
              if remain >= index and index != 1 do
                (point_bytes <<< (next_index * 8))
              else
                point_bytes
              end

            { next_index, (last_m ||| right_side) }
           end)
    end

    state
    |> State.apply_block(last_m, c_pass)

      iex> SipHash.hash("0123456789ABCDEF", "hello")
      "3D1974E948748CE2"

      iex> SipHash.hash("0123456789ABCDEF", "abcdefgh")
      "1AE57886F899E65F"

      iex> SipHash.hash("0123456789ABCDEF", "my long strings")
      "1323400B0804036D"

      iex> SipHash.hash("0123456789ABCDEF", "hello", case: :lower)
      "3d1974e948748ce2"
