base64: A modern Base64 library

[ bsd3, data, library ] [ Propose Tags ] [ Report a vulnerability ]

A performant, featureful RFC 4648 and 7049-compliant Base64 implementation


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
simd

Use bundled SIMD kernels where supported, with a scalar fallback

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.0.1.0, 0.1.0.0, 0.2.0.0, 0.3.0.0, 0.3.1.0, 0.3.1.1, 0.4.0, 0.4.1, 0.4.2, 0.4.2.1, 0.4.2.2, 0.4.2.3, 0.4.2.4, 1.0, 1.0.1, 2.0 (info)
Change log CHANGELOG.md
Dependencies base (>=4.18 && <4.23), bytestring (>=0.11 && <0.13), deepseq (>=1.4.4.0 && <1.6), text (>=2.0 && <2.3), text-short (>=0.1 && <0.2) [details]
Tested with ghc ==9.6.7 || ==9.8.4 || ==9.10.3 || ==9.12.4 || ==9.14.1
License BSD-3-Clause
Copyright (c) 2019-2026 Emily Pillmore
Author Emily Pillmore
Maintainer Emily Pillmore <emilypi@cohomolo.gy>
Uploaded by topos at 2026-10-13T23:47:24Z
Category Data
Home page https://github.com/emilypi/base64
Bug tracker https://github.com/emilypi/base64/issues
Source repo head: git clone https://github.com/emilypi/base64.git
Distributions Arch:1.0, Fedora:1.0, LTSHaskell:1.0, Stackage:1.0
Reverse Dependencies 41 direct, 3981 indirect [details]
Downloads 21601 total (64 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2026-10-13 [all 1 reports]

Readme for base64-2.0

[back to package description]

Base64

Build Status Hackage

Base64 encoding and decodings.

For the companion optics and pattern synonyms, see base64-lens.

Summary

The following types are supported for both std, padded url-safe, and unpadded url-safe alphabets:

  • Data.ByteString
  • Data.ByteString.Lazy
  • Data.ByteString.Short
  • Data.Text
  • Data.Text.Lazy
  • Data.Text.Short

Additionally this library has

  • Better performance than base64-bytestring for encode and decode.
  • Optics for handling more complex structures with Base64 representations via the base64-lens package
  • Parses standard Base64 into a validated Base64 value, and checks Base64url encodings
  • Rejects non-canonical encodings that do not roundtrip in other base64 libraries like ZE==.

The library supports GHC 9.6 through 9.14. Its dependencies are base, bytestring, deepseq, text, and text-short.

Upgrading to 2.0? See the migration guide for the replacement of isBase64 and isValidBase64, and the release notes for the optional SIMD implementation.

Parsing existing Base64

Use parseBase64 to validate externally supplied standard Base64 and retain the encoded value in a typed wrapper:

>>> import qualified Data.ByteString.Base64 as B64
>>> :set -XOverloadedStrings
>>> B64.parseBase64 "U3Vu"
Right "U3Vu"
>>> fmap B64.decodeBase64 (B64.parseBase64 "U3Vu")
Right "Sun"
>>> B64.parseBase64 "U3V="
Left "non-canonical encoding detected at offset: 2"

Each standard-alphabet module exports parseBase64 :: a -> Either Text (Base64 'StdPadded a), specialized to its string type. Parsing checks the alphabet, length, padding, and canonical padding bits, then returns the original encoded input. The Text variants validate Base64 independently of the decoded payload's UTF-8 validity; use decodeBase64UntypedWith to check that conversion.

parseBase64 replaces isBase64 and isValidBase64. For a Boolean check, use isRight . parseBase64 from Data.Either. Unlike the old isValidBase64, this rejects missing padding and non-canonical encodings. The URL-specific validators isBase64Url and isValidBase64Url retain their existing behavior.

Optional SIMD

Enable the manual simd Cabal flag to use bundled SIMD kernels for standard and URL-safe encoding and strict decoding, including the typed decoders:

cabal build -fsimd
cabal test -fsimd --test-show-details=direct

The flag is off by default. ARM64 uses NEON; x86-64 selects AVX2 when the CPU and operating system support it, then SSSE3 on older processors. Other targets and short inputs use the existing Haskell loops. No external C library is required. Remainders, padding checks, canonical-encoding checks, and error messages still use the Haskell code. Lenient decoding remains scalar.

Test both configurations and compare optimized benchmark builds separately:

cabal test -f-simd --builddir=dist-scalar --test-show-details=direct
cabal test -fsimd --builddir=dist-simd --test-show-details=direct
cabal bench -f-simd --builddir=dist-scalar -O2 --benchmark-options='--csv scalar.csv'
cabal bench -fsimd --builddir=dist-simd -O2 --benchmark-options='--csv simd.csv'

Benchmark names identify the selected flag configuration. The suite covers standard Base64 and padded/unpadded Base64url, encoding and typed/untyped decoding, short and large buffers, and sliced inputs. The test suite exercises block boundaries, scalar tails, slices, invalid input, and wrapper types in both configurations; CI also runs native memory checks on x86-64 and ARM64, explicitly requiring AVX2 on Linux x86-64 and checking the SSSE3 and scalar fallbacks separately.

For native kernel measurements, a standalone benchmark validates every case against scalar output and checks both alphabets. It times pseudorandom, cycling, and repeated inputs at two alignments. It reports the detected backend and writes CSV results:

cc -O2 -std=c99 -Icbits cbits/base64_simd.c benchmarks/simd-native.c -o base64-native-bench
./base64-native-bench --seconds 0.05 --rounds 5 > native.csv

Add --url to time the URL alphabet, or --pattern random to select one input distribution. On x86-64, compile a second executable with -DHS_BASE64_SIMD_FORCE_SSSE3 to compare the older backend on the same CPU. These measurements cover native prefixes only; use the Cabal benchmarks above to include Haskell allocation and scalar tails.