base64-1.0: A modern Base64 library

Copyright | (c) 2019-2023 Emily Pillmore
License | BSD-style
Maintainer | Emily Pillmore <emilypi@cohomolo.gy>
Stability | stable
Portability | non-portable
Safe Haskell | None
Language | Haskell2010

Data.Text.Short.Encoding.Base64.URL

Contents

- Encoding
- Decoding
- Validation

Description

This module contains `ShortText`-valued combinators implementing the RFC 4648 specification for the Base64url encoding format. This includes strictly padded/unpadded and lenient decoding variants, and external + internal validations for canonicity.

Synopsis

- encodeBase64 :: ShortText -> Base64 'UrlPadded ShortText
- encodeBase64Unpadded :: ShortText -> Base64 'UrlUnpadded ShortText
- decodeBase64 :: forall (k :: Alphabet). UrlAlphabet k => Base64 k ShortText -> ShortText
- decodeBase64Untyped :: ShortText -> Either Text ShortText
- decodeBase64UntypedWith :: (ShortByteString -> Either err ShortText) -> ShortByteString -> Either (Base64Error err) ShortText
- decodeBase64Unpadded :: Base64 'UrlUnpadded ShortText -> ShortText
- decodeBase64UnpaddedUntyped :: ShortText -> Either Text ShortText
- decodeBase64UnpaddedUntypedWith :: (ShortByteString -> Either err ShortText) -> ShortByteString -> Either (Base64Error err) ShortText
- decodeBase64Padded :: Base64 'UrlPadded ShortText -> ShortText
- decodeBase64PaddedUntyped :: ShortText -> Either Text ShortText
- decodeBase64PaddedUntypedWith :: (ShortByteString -> Either err ShortText) -> ShortByteString -> Either (Base64Error err) ShortText
- decodeBase64Lenient :: ShortText -> ShortText
- isBase64Url :: ShortText -> Bool
- isValidBase64Url :: ShortText -> Bool

# Encoding

encodeBase64 :: ShortText -> Base64 'UrlPadded ShortText #

Encode a `ShortText` value in Base64url with padding.

See: RFC-4648 section 5

### Examples:

    >>> encodeBase64 "<<?>>"
    "PDw_Pj4="

encodeBase64Unpadded :: ShortText -> Base64 'UrlUnpadded ShortText #

Encode a `ShortText` value in Base64url without padding.

See: RFC-4648 section 3.2

### Examples:

    >>> encodeBase64Unpadded "<<?>>"
    "PDw_Pj4"

# Decoding

decodeBase64 :: forall (k :: Alphabet). UrlAlphabet k => Base64 k ShortText -> ShortText #

Decode an arbitrarily padded Base64url-encoded `ShortText` value.

For typed values: - If a padded value is required, use `decodeBase64Padded` - If an unpadded value is required, use `decodeBase64Unpadded`

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64 $ assertBase64 @'UrlPadded "PDw_Pj4="
    "<<?>>"

    >>> decodeBase64 $ assertBase64 @'UrlUnpadded "PDw_Pj4"
    "<<?>>"

decodeBase64Untyped :: ShortText -> Either Text ShortText #

Decode an untyped padded Base64url-encoded `ShortText` value. If its length is not a multiple of 4, then padding chars will be added to fill out the input to a multiple of 4 for safe decoding as base64url encodings are optionally padded.

For a decoder that fails on unpadded input, use `decodeBase64Unpadded`.

Note: This function makes sure that decoding is total by deferring to `decodeUtf8`. This will always round trip for any valid Base64-encoded text value, but it may not round trip for bad inputs. The onus is on the caller to make sure inputs are valid. If unsure, defer to `decodeBase64With` and pass in a custom decode function.

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64Untyped "PDw_Pj4="
    Right "<<?>>"

    >>> decodeBase64Untyped "PDw_Pj4"
    Right "<<?>>"

    >>> decodeBase64Untyped "PDw-Pg="
    Left "Base64-encoded bytestring has invalid padding"

    >>> decodeBase64Untyped "PDw-Pg"
    Right "<<>>"

decodeBase64UntypedWith #

Arguments

:: (ShortByteString -> Either err ShortText) | convert a bytestring to text (e.g. `decodeUtf8'`)
-> ShortByteString | Input text to decode
-> Either (Base64Error err) ShortText |

Attempt to decode an untyped `ShortByteString` value as Base64url, converting from `ByteString` to `ShortText` according to some encoding function. In practice, This is something like `decodeUtf8'`, which may produce an error.

See: RFC-4648 section 4

### Examples:

    decodeBase64With decodeUtf8'
      :: ShortByteString -> Either (Base64Error UnicodeException) ShortText

decodeBase64Unpadded :: Base64 'UrlUnpadded ShortText -> ShortText #

Decode an unpadded Base64url encoded `ShortText` value.

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64Unpadded $ assertBase64 @'UrlUnpadded "PDw_Pj4"
    "<<?>>"

decodeBase64UnpaddedUntyped :: ShortText -> Either Text ShortText #

Decode an untyped, unpadded Base64url encoded `ShortText` value.

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64UnpaddedUntyped "PDw_Pj4"
    Right "<<?>>"

    >>> decodeBase64UnpaddedUntyped "PDw_Pj4="
    Left "Base64-encoded bytestring has invalid padding"

decodeBase64UnpaddedUntypedWith #

Arguments

:: (ShortByteString -> Either err ShortText) | convert a bytestring to text (e.g. `decodeUtf8'`)
-> ShortByteString | Input text to decode
-> Either (Base64Error err) ShortText |

Attempt to decode an untyped, unpadded `ShortByteString` value as Base64url, converting from `ShortByteString` to `ShortText` according to some encoding function. In practice, This is something like `decodeUtf8'`, which may produce an error.

See: RFC-4648 section 4

### Examples:

    decodeBase64UnpaddedWith decodeUtf8'
      :: ShortByteString -> Either (Base64Error UnicodeException) ShortText

decodeBase64Padded :: Base64 'UrlPadded ShortText -> ShortText #

Decode a padded Base64url encoded `ShortText` value

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64Padded $ assertBase64 @'UrlPadded "PDw_Pj4="
    "<<?>>"

decodeBase64PaddedUntyped :: ShortText -> Either Text ShortText #

Decode an untyped, padded Base64url encoded `ShortText` value

See: RFC-4648 section 4

### Examples:

    >>> decodeBase64PaddedUntyped "PDw_Pj4="
    Right "<<?>>"

    >>> decodeBase64PaddedUntyped "PDw_Pj4"
    Left "Base64-encoded bytestring requires padding"

decodeBase64PaddedUntypedWith #

Arguments

:: (ShortByteString -> Either err ShortText) | convert a bytestring to text (e.g. `decodeUtf8'`)
-> ShortByteString | Input text to decode
-> Either (Base64Error err) ShortText |

Attempt to decode an untyped, padded `ShortByteString` value as Base64url, converting from `ByteString` to `ShortText` according to some encoding function. In practice, This is something like `decodeUtf8'`, which may produce an error.

See: RFC-4648 section 4

### Examples:

    decodeBase64With decodeUtf8'
      :: ShortByteString -> Either (Base64Error UnicodeException) ShortText

decodeBase64Lenient :: ShortText -> ShortText #

Leniently decode an untyped, unpadded Base64url-encoded `ShortText`. This function will not generate parse errors. If input data contains padding chars, then the input will be parsed up until the first pad character.

Note: This is not RFC 4648-compliant.

### Examples:

    >>> decodeBase64Lenient "PDw_Pj4="
    "<<?>>"

    >>> decodeBase64Lenient "PDw_%%%$}Pj4"
    "<<?>>"

# Validation

isBase64Url :: ShortText -> Bool #

Tell whether an untyped `ShortText` value is Base64url-encoded.

### Examples:

    >>> isBase64Url "PDw_Pj4="
    True

    >>> isBase64Url "PDw_Pj4"
    True

    >>> isBase64Url "PDw_Pj"
    False

isValidBase64Url :: ShortText -> Bool #

Tell whether an untyped `ShortText` value is a valid Base64url format.

This will not tell you whether or not this is a correct Base64url representation, only that it conforms to the correct shape. To check whether it is a true Base64 encoded `ShortText` value, use `isBase64Url`.

### Examples:

    >>> isValidBase64Url "PDw_Pj4="
    True

    >>> isValidBase64Url "PDw_Pj"
    True

    >>> isValidBase64Url "%"
    False