       true -> string(data, pos + 2, [Map.get(@escapes, char)|chars])
     end
   end
-  defp string(<<@escape>> <> _data, pos, _chars),
+  defp string(<<?\\>> <> _data, pos, _chars),
     do: throw {:string, pos}
   defp string(<<char>> <> data, pos, chars),
     do: string(data, pos + 1, [char|chars])
 
   defp unicode(<<a1, b1, c1, d1, ?\\, ?u, a2, b2, c2, d2>> <> data, pos, chars)
-    when a1 in @surrogate_a and a2 in @surrogate_a and b1 in @surrogate_b1 and b2 in @surrogate_b2 do
+    when a1 in 'dD' and a2 in 'dD' and b1 in '89abAb' and b2 in 'cedfCDEF' do
     hi = List.to_integer([a1, b1, c1, d1], 16)
     lo = List.to_integer([a2, b2, c2, d2], 16)
     codepoint = 0x10000 + ((hi &&& 0x03FF) <<< 10) + (lo &&& 0x03FF)

  end

  defp json(<<char>> <> data, pos)
    when char in @whitespace,
    do: json(data, pos + 1)
  defp json(<<char>> <> data, pos)
    when char == @quotation_mark,
    do: string(data, pos + 1, [])
  defp json(<<char>> <> data, pos)
    when char == @left_square_bracket,
    do: list(data, pos + 1, [])
  defp json(<<char>> <> data, pos)
    when char == @left_curly_bracket,
    do: map(data, pos + 1, [])
  defp json(<<char>> <> data, pos)
    when char in '-0123456789',
    do: number(data, pos + 1, [char], (if char == ?-, do: :minus, else: :digit))
  defp json(<<"true">> <> data, pos),
    do: {true, data, pos + 4}
  defp json(<<"false">> <> data, pos),
    do: {false, data, pos + 5}
  defp json(<<"null">> <> data, pos),
    do: {nil, data, pos + 4}
  defp json(_data, pos),
    do: throw {:json, pos + 1}

  defp key(<<char>> <> data, pos)
    when char in @whitespace,
    do: key(data, pos + 1)
  defp key(<<char>> <> data, pos)
    when char == @quotation_mark,
    do: string(data, pos + 1, [])
  defp key(_data, pos),
    do: throw {:key, pos}

  defp number(<<char>> <> data, pos, chars, _last)
    when char in @digits,
    do: number(data, pos + 1, [chars,char], :digit)
  defp number(<<?.>> <> _data, pos, _chars, :minus),
    do: throw {:number, pos + 1}
  defp number(<<?.>> <> data, pos, chars, _last),
    do: float(data, pos + 1, [chars, ?.], :full_stop)
  defp number(<<char>> <> _data, pos, _chars, :minus)
    when char in 'eE',
    do: throw {:number, pos}
  defp number(<<char>> <> data, pos, chars, _last)
    when char in 'eE',
    do: exponential(data, pos + 1, [chars, '.0e'], :exp)
  defp number(_data, pos, _chars, :minus),
    do: throw {:number, pos}
