base32-0.3.1.0: Fast RFC 4648-compliant Base32 encoding
Copyright(c) 2020 Emily Pillmore
LicenseBSD-style
MaintainerEmily Pillmore <emilypi@cohomolo.gy>
StabilityExperimental
Portabilityportable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.ByteString.Base32.Internal

Description

Internal module defining the encoding and decoding processes and tables.

Synopsis

Documentation

encodeBase32_ :: Addr# -> ByteString -> ByteString Source #

Head of the padded base32 encoding loop.

This function takes an alphabet in the form of an unboxed Addr#, allocates the correct number of bytes that will be written, and executes the inner encoding loop against that data.

encodeBase32NoPad_ :: Addr# -> ByteString -> ByteString Source #

Head of the unpadded base32 encoding loop.

This function takes an alphabet in the form of an unboxed Addr#, allocates the correct number of bytes that will be written, and executes the inner encoding loop against that data.

decodeBase32_ :: Ptr Word8 -> ByteString -> IO (Either Text ByteString) Source #

Head of the base32 decoding loop.

This function takes a base32-decoding lookup table and base32-encoded bytestring, allocates the correct number of bytes that will be written, and executes the inner decoding loop against that data.

validateBase32 :: ByteString -> ByteString -> Bool Source #

Validate a base32-encoded bytestring against some alphabet.

validateLastNPads :: Int -> ByteString -> IO (Either Text ByteString) -> Either Text ByteString Source #

This function checks that the last N-chars of a bytestring are '=' and, if true, fails with a message or completes some io action.

This is necessary to check when decoding permissively (i.e. filling in padding chars). Consider the following 8 cases of a string of length l:

  • l = 0 mod 8: No pad chars are added, since the input is assumed to be good.
  • l = 1 mod 8: Never an admissible length in base32
  • l = 2 mod 8: 6 padding chars are added. If padding chars are present in the string, they will fail as to decode as final quanta
  • l = 3 mod 8: Never an admissible length in base32
  • l = 4 mod 8: 4 padding chars are added. If 2 padding chars are present in the string this can be "completed" in the sense that it now acts like a string `l == 2 mod 8` with 6 padding chars, and could potentially form corrupted data.
  • l = 5 mod 8: 3 padding chars are added. If 3 padding chars are present in the string, this could form corrupted data like in the previous case.
  • l = 6 mod 8: Never an admissible length in base32
  • l = 7 mod 8: 1 padding char is added. If 5 padding chars are present in the string, this could form corrupted data like the previous cases.

Hence, permissive decodes should only fill in padding chars when it makes sense to add them. That is, if an input is degenerate, it should never succeed when we add padding chars. We need the following invariant to hold:

  B32.decodeUnpadded | B32.decodePadded ~ B32.decode