Strings and masks

Hi all!

I have a question that I feel there is a better solution, but after fiddling with it, just couldn’t find it.

I’m working with credit and debit cards in a Phoenix application, and I have to do some card number masking.
I expect to have something like:

  credit_card = 
  "400443412313"
  |> creditMyMaskModule.mask(?*) # * is the masking character
  IO.puts credit_card # puts ********2313

The code that I’ve written is as follows:

defp put_mask(changeset) do
    case get_field(changeset, :pan) do
      nil -> changeset
      pan ->
        ch = with gr = String.graphemes(pan),
                  [_|final] <- Enum.chunk(gr, 8, 8, []),
                  final = Enum.join(final) do
               {:ok, put_change(changeset, :pan_mask, String.rjust(final, 8, ?*))}
             end
        case ch do
          {:ok, ok} -> ok
          _ -> changeset
        end
    end
  end

(and, as an addendum, is the way that I work with strings, and it feels clumsy)
Anyway, is there a better way to do this?

Thanks!

1 Like

I managed to do it a more clean way:

masked = str
        |> String.slice(-4, 4)
        |> String.rjust(String.length(str), ?*)
6 Likes