Packages
comeonin
1.2.1
5.5.1
5.5.0
5.4.0
5.3.3
5.3.2
5.3.1
5.3.0
5.2.0
5.1.3
5.1.2
5.1.1
5.1.0
5.0.0
4.1.2
4.1.1
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.0
3.2.0
3.1.0
3.0.2
3.0.1
3.0.0
2.6.0
2.5.3
2.5.2
2.5.1
2.5.0
2.4.0
2.3.1
2.3.0
2.2.0
2.1.1
2.1.0
2.0.3
2.0.2
2.0.1
2.0.0
1.6.0
1.5.0
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
A specification for password hashing libraries
Current section
Files
Jump to
Current section
Files
lib/comeonin/bcrypt/base64.ex
defmodule Comeonin.Bcrypt.Base64 do
@moduledoc """
Module that provides base64 encoding for bcrypt.
"""
use Bitwise
@decode_map {:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:ws,:ws,:bad,:bad,:ws,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:ws,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,0,1,
54,55,56,57,58,59,60,61,62,63,:bad,:bad,:bad,:eq,:bad,:bad,
:bad,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24,25,26,27,:bad,:bad,:bad,:bad,:bad,
:bad,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,
43,44,45,46,47,48,49,50,51,52,53,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,
:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad,:bad}
@doc """
Encode using a base64 alphabet adapted for bcrypt.
## Examples
iex> Comeonin.Bcrypt.Base64.encode 'spamandeggs'
'a1/fZUDsXETlX1K'
"""
def encode(words), do: encode_l(words)
@doc """
Decode using a base64 alphabet adapted for bcrypt.
## Examples
iex> Comeonin.Bcrypt.Base64.decode 'a1/fZUDsXETlX1K'
'spamandeggs'
"""
def decode(words), do: decode_l(words, [])
defp b64e(val) do
elem({?., ?/, ?A, ?B, ?C, ?D, ?E, ?F, ?G, ?H, ?I, ?J, ?K, ?L,
?M, ?N, ?O, ?P, ?Q, ?R, ?S, ?T, ?U, ?V, ?W, ?X,
?Y, ?Z, ?a, ?b, ?c, ?d, ?e, ?f, ?g, ?h, ?i, ?j, ?k, ?l,
?m, ?n, ?o, ?p, ?q, ?r, ?s, ?t, ?u, ?v, ?w, ?x,
?y, ?z, ?0, ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9}, val)
end
defp encode_l([]), do: []
defp encode_l([a]) do
[b64e(a >>> 2),
b64e((a &&& 3) <<< 4)]
end
defp encode_l([a,b]) do
[b64e(a >>> 2),
b64e(((a &&& 3) <<< 4) ||| (b >>> 4)),
b64e((b &&& 15) <<< 2)]
end
defp encode_l([a,b,c|ls]) do
bb = (a <<< 16) ||| (b <<< 8) ||| c
[b64e(bb >>> 18),
b64e((bb >>> 12) &&& 63),
b64e((bb >>> 6) &&& 63),
b64e(bb &&& 63) | encode_l(ls)]
end
defp decode_l([], a), do: a
defp decode_l([c1,c2], a) do
bits2x6 = (b64d(c1) <<< 18) ||| (b64d(c2) <<< 12)
octet1 = bits2x6 >>> 16
a ++ [octet1]
end
defp decode_l([c1,c2,c3], a) do
bits3x6 = (b64d(c1) <<< 18) ||| (b64d(c2) <<< 12) ||| (b64d(c3) <<< 6)
octet1 = bits3x6 >>> 16
octet2 = (bits3x6 >>> 8) &&& 0xff
a ++ [octet1,octet2]
end
defp decode_l([c1,c2,c3,c4| cs], a) do
bits4x6 = (b64d(c1) <<< 18) ||| (b64d(c2) <<< 12) ||| (b64d(c3) <<< 6) ||| b64d(c4)
octet1 = bits4x6 >>> 16
octet2 = (bits4x6 >>> 8) &&& 0xff
octet3 = bits4x6 &&& 0xff
decode_l(cs, a ++ [octet1,octet2,octet3])
end
defp b64d(val) do
b64d_ok(elem(@decode_map, val))
end
defp b64d_ok(val) when is_integer(val), do: val
defp b64d_ok(val) do
raise ArgumentError, message: "invalid character: #{val}"
end
end