A Base91 Encoder & Decoder for Haskell
Switch branches/tags
Clone or download
Latest commit fa58a84 Apr 29, 2018



A Base91 Encoder & Decoder for Haskell, written by Alvaro J. Genial.

Build Status Hackage


This library (and command-line utility) implement generic bidirectional Base91 encoding & decoding following the specification.


The codebase should be considered stable; it is documented using haddock and tested using QuickCheck.


Base91 is a scheme that allows arbitrary binary data (a sequence of 8-bit bytes, or octets) to be represented using an alphabet consisting of 91 of the 95 printable ASCII characters. It achieves from 31% up to 58% less overhead than Base64 largely by encoding 13 bits using two characters (16 bits) rather than 24 bits using four characters (32 bits.)


'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', '!', '#', '$',
'%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=',
'>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"'


The base91 package exposes a single generic Codec.Binary.Base91 module with two functions, the duals of each other:

  • encode: Encodes a byte (Word8) input sequence (e.g. [Word8], ByteString, etc.) to a character (Char) output sequence (e.g. [Char], Data.Text, etc.).
  • decode: Decodes a character (Char) input sequence (e.g. [Char], Data.Text, etc.) to a byte (Word8) output sequence (e.g. [Word8], ByteString, etc.).

(Note that because the functions' signatures are generic, in some cases an explicit output type must be provided; see the example.)


$ ghci Codec.Binary.Base91
λ let bytes = [72,101,108,108,111,44,32,119,111,114,108,100,33,10]
λ encode bytes :: String -- equal to "Hello, World!\n"
λ decode ">OwJh>}A\"=r@@Y?FF" :: [Word8]


$ echo "Hello, World!" | base91 --encode
$ echo ">OwJh>}AQ;r@@Y?FF" | base91 --decode
Hello, World!


import System.Environment (getProgName)

import qualified Codec.Binary.Base91  as Base91
import qualified Data.ByteString      as BS
import qualified Data.Text.IO         as T

main :: IO ()
main = getProgName >>= \name -> case name of
  "b91enc" -> BS.getContents >>= T.putStrLn . Base91.encode
  "b91dec" -> T.getContents >>= BS.putStr . Base91.decode
  _        -> error "invalid program name"


The latest documentation can be found on Hackage.


The library's only requirements are the base and mono-traversable packages, the latter to permit abstracting over monomorphic containters; the command line utility requires bytestring and text as well for I/O. Testing requires all the aforementioned plus the QuickCheck package. (See base91.cabal for details.)


This library is distributed under the MIT LICENSE.