diff --git a/CHANGE_LOG.md b/CHANGE_LOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGE_LOG.md
@@ -0,0 +1,36 @@
+Hackage [`basesystems`](http://hackage-content.haskell.org/package/basesystems)
+package change log:
+=====================================================================
+
+## Version 1.0.0.0
+
+Finally initialize git repository! This version introduces the package to the
+Hackage repository and the provides an interface for encoding/decoding digit
+strings in several common numeric basesystems. Namely, this version provides
+the following modules for processing this data:
+
+### `Data.BaseSystem`
+
+Provides the type-class for `BaseSystem` and the `encoder` and `decoder` methods
+and generic implementations for 2 kinds of basesystems:
+
+- `RadixSystem` for typical basesystems such as base10
+- `BitwiseSystem` for special basesystems such as base64 and base32
+
+### `Data.BaseSystems`:
+
+Defines common basesystems using the definitions found in
+`Data.BaseSystem.Alphabets`. See the project source code for the names of
+currently provided implementations.
+
+### Other modules:
+
+- `Data.BaseSystem.Alphabet` data structure definition for basesystem digit
+  alphabets and methods for querying alphabet information.
+- `Data.BaseSystem.Alphabets` definitions for specific digit alphabets for
+  implementing basesystems.
+- `Data.BaseSystem.Internal` provides useful methods used across modules. For
+  example the `packInteger` and `bytesToInteger` provides ways to convert
+  Integers to ByteString and vice-versa, which is handy for GHCi and unit
+  tests (so that we don't have to write numbers as ByteStrings before using the
+  encoders or decoders).
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,28 @@
+BSD 3-Clause License
+
+Copyright (c) 2026, Zoey McBride <zoeymcbride@mailbox.org>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,62 @@
+basesystems
+===========
+
+This project code contains for Encoding/Decoding number basesystems in Haskell.
+It's implemented in a strategy pattern style where `BaseSystem` is a type-class
+which provides the `encoder` and `decoder` methods:
+
+```haskell
+class BaseSystem a where
+  encoder :: a -> ByteString -> String
+  decoder :: a -> String -> Maybe ByteString
+```
+
+Then we define data structure representations for `a` and implement each
+method with the data from `a`. For instance, this is how the implementations
+of base64 and base10 are distinguished.
+
+Example
+-------
+
+```haskell
+ghci> import Data.BaseSystem
+ghci> import Data.BaseSystems
+ghci> import Data.BaseSystem.Internal (packInteger)
+ghci>
+ghci> encoder base10 (packInteger 123) -- "123"
+ghci> decoder base10 "123"             -- Just <123 as binary in ByteString>
+ghci> encoder base64 (packInteger 123) -- "ew=="
+ghci> decoder base64 "ew=="            -- Just <123 as binary in ByteString>
+```
+
+Coverage
+--------
+
+This project aims to eventually implement most if not all of the
+[mulitbase specification's basesytems list](
+https://github.com/multiformats/multibase?tab=readme-ov-file#multibase-table).
+
+Currently, the following basesystems are supported:
+- base2
+- base10
+- base16(upper/lower)
+- base32(upper/lower) w/pad + nopad
+- base32hex(lower/upper) w/pad + nopad
+- base58btc
+- base64 w/pad + nopad
+- base64url w/pad + nopad
+
+Unit testing
+------------
+
+Since these functions can have such a large amount of inputs/outputs + possible
+edge cases, we generate test sets in bulk from scripts in the python folder to
+JSON format. Code for running tests can be found at the main [ipfshs repo](
+https://git.sr.ht/~z0/ipfshs).
+
+License
+-------
+
+This project is free software and is provided under the BSD 3-clause licensing
+agreement. Copyright (C) 2026 Zoey McBride <[zoeymcbride@mailbox.org](
+mailto:zoeymcbride@mailbox.org)>.
diff --git a/basesystems.cabal b/basesystems.cabal
new file mode 100644
--- /dev/null
+++ b/basesystems.cabal
@@ -0,0 +1,37 @@
+cabal-version:   3.0
+version:         1.0.0.0
+name:            basesystems
+build-type:      Simple
+author:          Zoey McBride
+maintainer:      zoeymcbride@mailbox.org
+license:         BSD-3-Clause
+license-file:    LICENSE.txt
+extra-doc-files: README.md, CHANGE_LOG.md
+category:        Numeric, Data, Serialization
+synopsis:        Implements encoders/decoders for basesystems
+description:
+    This package implements these encoder and decoder methods for numeric
+    basesystems and provides definitions for common basesystems like base16,
+    base58btc, base64, and more.
+
+source-repository head
+  type:     git
+  location: https://git.sr.ht/~z0/basesystems
+
+library
+    default-language: GHC2021
+    default-extensions: StrictData
+    ghc-options: -Wall -Wextra -Wno-unused-top-binds
+    hs-source-dirs: basesystems
+    exposed-modules:
+        Data.BaseSystem,
+        Data.BaseSystems,
+        Data.BaseSystem.Alphabet,
+        Data.BaseSystem.Alphabets,
+        Data.BaseSystem.Internal,
+    build-depends:
+        base ^>= 4.18,
+        array ^>= 0.5,
+        bytestring ^>= 0.11,
+        containers ^>= 0.6,
+        text ^>= 1.2,
diff --git a/basesystems/Data/BaseSystem.hs b/basesystems/Data/BaseSystem.hs
new file mode 100644
--- /dev/null
+++ b/basesystems/Data/BaseSystem.hs
@@ -0,0 +1,170 @@
+-- | Module      : Data.BaseSystem
+--   Description : Defines + implements the BaseSystem type-class
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : BSD-3-Clause
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides methods for encoding/decoding binary data to/from strings
+-- of digits in some basesystem. Digits can represent a sum of value placements
+-- (RadixSystem, eg: binary, base10) *OR* a concatination of fixed-width bit
+-- groups (BitwiseSystem, eg: base64, base32).
+module Data.BaseSystem
+  ( Encoder,
+    Decoder,
+    BaseSystem (encoder, decoder),
+  )
+where
+
+import Data.BaseSystem.Alphabet (Alphabet, alphaRadix)
+import Data.BaseSystem.Alphabet qualified as Alpha
+import Data.BaseSystem.Internal
+import Data.Bits ((.&.), (.<<.), (.>>.), (.|.))
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import Data.Maybe (fromJust, fromMaybe)
+import Data.Text qualified as Text
+
+-- | Type-class (interface) for implementing encode/decode functionality for
+-- some data structure w/ Alphabet `a`.
+class BaseSystem a where
+  encoder :: a -> Encoder
+  decoder :: a -> Decoder
+
+-- | Function signature for encoding some ByteString to String of digits.
+type Encoder = ByteString -> String
+
+-- | Function signature for decoding some String of digits to ByteString, given
+-- all digits in String are valid Symbols.
+type Decoder = String -> Maybe ByteString
+
+-- | Implements BaseSystem for number systems built by modular arithmetic w/ the
+-- radix.
+instance BaseSystem RadixSystem where
+  encoder :: RadixSystem -> ByteString -> String
+  encoder (RadixSystem _ abc) =
+    let radix = fromIntegral $ alphaRadix abc
+     in concatMap Text.unpack
+          . divModSymbols
+          . takeWhile divModContinue
+          . iterateInit (\(num, _) -> num `divMod` radix) mkDivMod
+          . bytesToInteger
+    where
+      -- Initial value to iterate on divMod.
+      mkDivMod numerator = (numerator, 0)
+      -- Predicates divMod iteration results.
+      divModContinue (nextinput, curresult) = nextinput > 0 || curresult > 0
+      -- Resolves the symbols from the result of iterating divMod.
+      divModSymbols =
+        reverse
+          . fromJust
+          . mapM (\(_, digit) -> Alpha.resolveSymbol abc digit)
+          . replaceNull [(undefined, 0)]
+
+  decoder :: RadixSystem -> String -> Maybe ByteString
+  decoder (RadixSystem _ abc) str =
+    let radix = fromIntegral $ alphaRadix abc
+     in binaryDecoder Nothing (Text.pack str) $
+          \curvalue symbol -> do
+            value <- Alpha.resolveValue abc symbol
+            return $ curvalue * radix + value
+
+-- | Resolves symbols from Alphabet for a BitwiseSystem's encoder. Partitions
+-- a ByteString into N sized bitgroups where N is the bitwidth of the Alphabet's
+-- radix. *IMPORTANT*: this function requires the groupsize to be a multiple of
+-- two because it generates a mask from subtracting it by 1.
+groupSymbols :: Alphabet -> Int -> Int -> ByteString -> [Alpha.Symbol]
+groupSymbols abc symbits groupsize groupbytes =
+  let groupint =
+        case bytesToInteger groupbytes of
+          groupnum
+            | fitsGroup groupsize groupbytes groupnum -> fromIntegral groupnum
+            | otherwise -> error "invalid group size"
+   in -- Crash if the implementation isn't complete
+      fromJust
+        -- Extract the value from the shift and resolve its symbol.
+        . mapM (Alpha.resolveSymbol abc . valueExtract . nextInt groupint)
+        -- Take all non-zero shifts.
+        . takeWhile (>= 0)
+        -- Generate a list of shift values from the # bits in groupbytes.
+        $ iterateInit shiftValue mkBitLength groupbytes
+  where
+    -- Gets the next int to extract group.
+    nextInt groupint shift = groupint .>>. shift
+    -- Extracts the first group from LSB from an Int.
+    valueExtract int = fromIntegral $ int .&. (alphaRadix abc - 1)
+    -- Finds the length in bits of a ByteString.
+    mkBitLength bstr = fromIntegral $ 8 * Bytes.length bstr
+    -- Gives the current shift value in iteration.
+    shiftValue bitstotal = bitstotal - symbits
+
+-- | Implements encoder/decoder for a BitwiseSystem.
+instance BaseSystem BitwiseSystem where
+  encoder :: BitwiseSystem -> ByteString -> String
+  encoder (BitwiseSystem _ abc symbits groupbytes _ padmethod) input =
+    let -- Total # of bytes from input.
+        bytestotal = Bytes.length input
+        -- Total # of bits from input.
+        bitstotal = fromIntegral (8 * bytestotal) :: Double
+        -- Actual # of symbols for the # of bits in bytes.
+        numsymbols = ceiling (bitstotal / fromIntegral symbits)
+        -- Minimum # of symbols to put in the resulting string.
+        putsymbols = max 2 numsymbols
+        -- Result from applying the padding method to the # of bytes.
+        padapply = paddingResolve <$> padmethod <*> Just bytestotal
+     in (++ fromMaybe "" padapply)
+          . take putsymbols
+          . concatMap (\(group, _) -> groupString group)
+          . takeWhile (\(group, _) -> Bytes.length group > 0)
+          . iterateInit (\(_, rest) -> Bytes.splitAt groupbytes rest) mkSplit
+          $ minimalBytes bytestotal
+    where
+      -- Inits the iteration for Bytes.splitAt.
+      mkSplit initial = (Bytes.empty, initial)
+      -- Creates a string of symbols from a ByteString splitAt.
+      groupString =
+        Text.unpack . Text.concat . groupSymbols abc symbits groupbytes
+      -- Gives the minimal amount of bytes to produce a correct encoding.
+      {-# INLINE minimalBytes #-}
+      minimalBytes bytestotal
+        | bytestotal == 0 = Bytes.pack [0, 0]
+        | bytestotal == 1 = Bytes.snoc input 0
+        | bytesmodulus /= 0 = Bytes.append input $ Bytes.replicate zeros 0
+        | otherwise = input
+        where
+          bytesmodulus = bytestotal `mod` groupbytes
+          zeros = groupbytes - bytesmodulus
+
+  decoder :: BitwiseSystem -> String -> Maybe ByteString
+  decoder (BitwiseSystem _ abc symbits _ groupsyms pm) str =
+    let -- Gives just padding char if not nothing.
+        padchar = paddingChar <$> pm
+        -- Creates symbol from maybe padding char.
+        padsymbol = Text.singleton <$> padchar
+        -- Removes the trailing padding chars from the Text of str.
+        nopad = Text.dropWhileEnd (\sym -> Just sym == padchar) $ Text.pack str
+        -- Gives the total available characters.
+        totalsyms = Text.length nopad
+        -- Finds the needs # of symbols for the final padding chars.
+        needsyms = groupsyms - (totalsyms `mod` groupsyms)
+        -- Gives the number of bits to correct for missing final padding chars.
+        needbits = needsyms * symbits
+        -- Offset to Integer to byte-align the bits in the final ByteString.
+        bytealign = 8 * ceiling (fromIntegral needbits / 8 :: Double)
+     in binaryDecoder (finalizeBits needsyms bytealign) nopad $
+          \curvalue symbol -> do
+            value <- Alpha.resolveValue abc symbol
+            return $
+              if Just symbol /= padsymbol
+                then (curvalue .<<. symbits) .|. value
+                else curvalue .<<. symbits
+    where
+      -- Finds the value for the expected amount of padding regardless if the
+      -- BaseSystem has a PaddingMethod or not.
+      {-# INLINE finalizeBits #-}
+      finalizeBits needsyms align
+        -- If the # of Symbols in last group is the groupsyms size, pass
+        | needsyms == groupsyms = Nothing
+        -- Find the needed # of bits and align the output to first byte.
+        | otherwise = Just $ \finalvalue ->
+            finalvalue .<<. (symbits * needsyms) .>>. align
diff --git a/basesystems/Data/BaseSystem/Alphabet.hs b/basesystems/Data/BaseSystem/Alphabet.hs
new file mode 100644
--- /dev/null
+++ b/basesystems/Data/BaseSystem/Alphabet.hs
@@ -0,0 +1,83 @@
+-- | Module      : Data.BaseSystem.Alphabet
+--   Description : Functions for Alphabets on BaseSystems
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : BSD-3-Clause
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Implements digit alphabets for BaseSystems.
+module Data.BaseSystem.Alphabet
+  ( Symbol,
+    Value,
+    Alphabet (alphaRadix, alphaHashId),
+    mkAlphabet,
+    resolveValue,
+    resolveSymbol,
+  )
+where
+
+import Data.Array.IArray (Array, (!?))
+import Data.Array.IArray qualified as Array
+import Data.Char (ord)
+import Data.Function (on)
+import Data.Map.Strict (Map)
+import Data.Map.Strict qualified as Map
+import Data.Text (Text)
+import Data.Text qualified as Text
+
+-- | Represents a symbol to act as a digit in a numbering system.
+type Symbol = Text
+
+-- | The value of a symbol in a number system.
+type Value = Integer
+
+-- | Stores the String hash for an Alphabet. Used for comparision.
+type HashId = Int
+
+-- | Represents a two-way mapping between symbol's values and values's symbols.
+data Alphabet = Alphabet
+  { alphaRadix :: Int,
+    alphaHashId :: HashId,
+    alphaValues :: Array Value Symbol,
+    alphaSymbols :: Map Symbol Value
+  }
+
+instance Eq Alphabet where
+  (==) = (==) `on` alphaHashId
+
+instance Ord Alphabet where
+  compare = compare `on` alphaHashId
+
+-- | Implements https://cp-algorithms.com/string/string-hashing.html
+mkHashId :: String -> Int
+mkHashId =
+  foldr (\term acc -> (term + acc) `mod` modprime) 0
+    . zipWith (\i ch -> baseprime ^ i * ord ch) [(0 :: Int) ..]
+  where
+    -- Should be around of characters in any given alphabet
+    baseprime = 53
+    -- Large prime to prevent most collisions (1/modulus chance)
+    modprime = 1_000_009
+
+-- | Creates an Alphabet from a given String by chunking the single unicode
+-- points into Symbols.
+mkAlphabet :: String -> Alphabet
+mkAlphabet str =
+  let text = Text.pack str
+      symbols = Text.chunksOf 1 text
+      numsymbols = Text.length text
+      arraybound = fromIntegral $ numsymbols - 1
+   in Alphabet
+        { alphaRadix = numsymbols,
+          alphaHashId = mkHashId str,
+          alphaValues = Array.listArray (0, arraybound) symbols,
+          alphaSymbols = Map.fromList $ zip symbols [0 ..]
+        }
+
+-- | /O(log n)/ Find a value from a symbol in an alphabet.
+resolveValue :: Alphabet -> Symbol -> Maybe Value
+resolveValue abc symbol = Map.lookup symbol $ alphaSymbols abc
+
+-- | /O(1)/ Find a symbol from a value in an alphabet.
+resolveSymbol :: Alphabet -> Value -> Maybe Symbol
+resolveSymbol abc value = alphaValues abc !? value
diff --git a/basesystems/Data/BaseSystem/Alphabets.hs b/basesystems/Data/BaseSystem/Alphabets.hs
new file mode 100644
--- /dev/null
+++ b/basesystems/Data/BaseSystem/Alphabets.hs
@@ -0,0 +1,83 @@
+-- | Module      : Data.BaseSystem.Alphabets
+--   Description : Provides alphabets for common base-encodings
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : BSD-3-Clause
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Defines common Alphabets for BaseSystems.
+module Data.BaseSystem.Alphabets
+  ( binary,
+    decimal,
+    hexlower,
+    hexupper,
+    btc58,
+    b32lower,
+    b32upper,
+    b32hexlower,
+    b32hexupper,
+    b64,
+    b64url,
+  )
+where
+
+import Data.BaseSystem.Alphabet
+
+-- | Represents base2.
+binary :: Alphabet
+binary = mkAlphabet "01"
+
+-- | Represents base10.
+decimal :: Alphabet
+decimal = mkAlphabet $ '0' : ['1' .. '9']
+
+-- | Represents base16 w/ upper case A-F.
+hexupper :: Alphabet
+hexupper = mkAlphabet $ ['0'] ++ ['1' .. '9'] ++ ['A' .. 'F']
+
+-- | Represents base16 w/ lower case a-f.
+hexlower :: Alphabet
+hexlower = mkAlphabet $ ['0'] ++ ['1' .. '9'] ++ ['a' .. 'f']
+
+-- | Represents Bitcoin's base58.
+btc58 :: Alphabet
+btc58 =
+  mkAlphabet $
+    ['1' .. '9']
+      ++ ['A' .. 'H']
+      ++ ['J' .. 'N']
+      ++ ['P' .. 'Z']
+      ++ ['a' .. 'k']
+      ++ ['m' .. 'z']
+
+b32lower :: Alphabet
+b32lower = mkAlphabet $ ['a' .. 'z'] ++ ['2' .. '7']
+
+b32upper :: Alphabet
+b32upper = mkAlphabet $ ['A' .. 'Z'] ++ ['2' .. '7']
+
+b32hexupper :: Alphabet
+b32hexupper = mkAlphabet $ ['0'] ++ ['1' .. '9'] ++ ['A' .. 'V']
+
+b32hexlower :: Alphabet
+b32hexlower = mkAlphabet $ ['0'] ++ ['1' .. '9'] ++ ['a' .. 'v']
+
+-- | Represents base64 w/o padding implemented.
+b64 :: Alphabet
+b64 =
+  mkAlphabet $
+    ['A' .. 'Z']
+      ++ ['a' .. 'z']
+      ++ ['0']
+      ++ ['1' .. '9']
+      ++ ['+', '/']
+
+-- | Represents base64 w/o padding implemented.
+b64url :: Alphabet
+b64url =
+  mkAlphabet $
+    ['A' .. 'Z']
+      ++ ['a' .. 'z']
+      ++ ['0']
+      ++ ['1' .. '9']
+      ++ ['-', '_']
diff --git a/basesystems/Data/BaseSystem/Internal.hs b/basesystems/Data/BaseSystem/Internal.hs
new file mode 100644
--- /dev/null
+++ b/basesystems/Data/BaseSystem/Internal.hs
@@ -0,0 +1,140 @@
+-- | Module      : Data.BaseSystem.Internal
+--   Description : Provides common resources for multibase
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : BSD-3-Clause
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Common data definitions and helper functions for this library.
+module Data.BaseSystem.Internal
+  ( -- * BaseSystem data structures
+    RadixSystem (..),
+    PaddingMethod (..),
+    BitwiseSystem (..),
+
+    -- * List utilities
+    replaceNull,
+    iterateInit,
+
+    -- * ByteString utilities
+    bytesToInteger,
+    packInteger,
+    fitsGroup,
+
+    -- * Decoder implementations
+    binaryDecoder,
+  )
+where
+
+import Control.Monad (foldM)
+import Data.BaseSystem.Alphabet (Alphabet)
+import Data.BaseSystem.Alphabet qualified as Alpha
+import Data.Bits ((.&.), (.<<.), (.>>.), (.|.))
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import Data.Maybe (fromMaybe)
+import Data.Text (Text)
+import Data.Text qualified as Text
+
+-- | Implements BaseSystem over base radix modulus.
+data RadixSystem = RadixSystem
+  { -- | Used to implement instance of Show.
+    radixShow :: String,
+    -- | Alphabet for the base system.
+    radixAlpha :: Alphabet
+  }
+
+instance Show RadixSystem where
+  show = radixShow
+
+-- | Implements padding for encoding BitwiseSystem.
+data PaddingMethod = PaddingMethod
+  { -- | Gives the char to use as padding.
+    paddingChar :: Char,
+    -- | Provides the callback to resolve the padding from # of bytes.
+    paddingResolve :: Int -> String
+  }
+
+-- | Implements BaseSystem over series of bit groups.
+data BitwiseSystem = BitwiseSystem
+  { -- | String used to implement instance of Show.
+    bitwiseShow :: String,
+    -- | Base system alphabet.
+    bitwiseAlpha :: Alphabet,
+    -- | # of bits per symbol
+    bitwiseSymBits :: Int,
+    -- | # of bytes to be processed into symbols in encoding.
+    bitwiseGroupBytes :: Int,
+    -- | # of bytes forming a group to find padding in decoding.
+    bitwiseGroupSymbols :: Int,
+    -- | Gives the method for padding.
+    bitwisePadMethod :: Maybe PaddingMethod
+  }
+
+instance Show BitwiseSystem where
+  show = bitwiseShow
+
+-- | Return the the first param if the second param is empty.
+{-# INLINE replaceNull #-}
+replaceNull :: [a] -> [a] -> [a]
+replaceNull replace xs
+  | null xs = replace
+  | otherwise = xs
+
+-- | Wraps iterate to compose with an intermediary type constructor.
+iterateInit :: (b -> b) -> (a -> b) -> a -> [b]
+iterateInit f iterinit = drop 1 . iterate f . iterinit
+
+-- | Builds an Integer from ByteString.
+bytesToInteger :: ByteString -> Integer
+bytesToInteger =
+  Bytes.foldl' (\acc x -> (acc .<<. 8) .|. fromIntegral x) 0
+    . Bytes.dropWhile (== 0)
+
+-- | Encode an Integer's numeric value in a ByteString as raw base2 binary
+-- values from the the Integer's bit values.
+packInteger :: Integer -> ByteString
+packInteger =
+  -- This code can be optimized; if we precalculate the length of the integer
+  -- in bits we can mask from the other direction using left shifts, and remove
+  -- the call to reverse, maybe we can even use a list comprehension to build
+  -- in place for Bytes.pack
+  let maskbyte = (.&. 0xFF)
+      shiftbyte = (.>>. 8)
+   in Bytes.pack
+        . replaceNull [0]
+        . reverse
+        . map (\(_, byte) -> fromIntegral byte)
+        . takeWhile (\(rest, byte) -> rest > 0 || byte > 0)
+        . iterateInit (\(input, _) -> (shiftbyte input, maskbyte input)) (,0)
+
+-- | Checks if an Integral a fits within a BitwiseSystem's group.
+{-# INLINE fitsGroup #-}
+fitsGroup :: Int -> ByteString -> Integer -> Bool
+fitsGroup groupsize groupbytes groupbits =
+  Bytes.length groupbytes <= groupsize
+    && minInt <= groupbits
+    && groupbits <= maxInt
+  where
+    minInt = fromIntegral (minBound :: Int)
+    maxInt = fromIntegral (maxBound :: Int)
+
+-- | Function to cleanup data in decoding.
+type FinalizeBits = Maybe (Integer -> Integer)
+
+-- Builds symbols from a number in decoding.
+type DecoderBuilder = Integer -> Alpha.Symbol -> Maybe Integer
+
+-- | Provides generic structure for decoding symbols into binary data
+-- ByteString.
+{-# INLINE binaryDecoder #-}
+binaryDecoder :: FinalizeBits -> Text -> DecoderBuilder -> Maybe ByteString
+binaryDecoder finalize text builder
+  | Text.null text = Nothing
+  | otherwise =
+      fmap (packInteger . applyFinalize)
+        . foldM builder 0
+        $ Text.chunksOf 1 text
+  where
+    -- If finalize exists, apply it, otherwise return the unchanged value.
+    applyFinalize value = fromMaybe value $ finalize <*> Just value
diff --git a/basesystems/Data/BaseSystems.hs b/basesystems/Data/BaseSystems.hs
new file mode 100644
--- /dev/null
+++ b/basesystems/Data/BaseSystems.hs
@@ -0,0 +1,151 @@
+-- | Module      : Data.BaseSystems
+--   Description : Provides default implementations for BaseSystem
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : BSD-3-Clause
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides common implementations for BaseSystem. These can be used
+-- by calling either `encoder <basename>` or `decoder <basename>`.
+module Data.BaseSystems
+  ( base2,
+    base10,
+    base16lower,
+    base16upper,
+    base32lower,
+    base32lowerNP,
+    base32upper,
+    base32upperNP,
+    base32hexlower,
+    base32hexlowerNP,
+    base32hexupper,
+    base32hexupperNP,
+    base58btc,
+    base64,
+    base64NP,
+    base64url,
+    base64urlNP,
+  )
+where
+
+import Data.BaseSystem.Alphabet (Alphabet)
+import Data.BaseSystem.Alphabets qualified as ABCs
+import Data.BaseSystem.Internal
+
+-- | Provides methods for building a base32 system, with an option to toggle
+-- padding.
+mkBaseSystem32 :: String -> Maybe Char -> Alphabet -> BitwiseSystem
+mkBaseSystem32 name padchar abc =
+  BitwiseSystem name abc symbits groupbytes groupsymbols $
+    PaddingMethod <*> padImpl <$> padchar
+  where
+    groupbytes = 5
+    groupsymbols = 8
+    symbits = 5
+    padImpl padding bytestotal
+      | bytestotal > 5 = padImpl padding $ bytestotal `mod` symbits
+      | bytestotal == 4 = [padding]
+      | bytestotal == 3 = replicate 3 padding
+      | bytestotal == 2 = replicate 4 padding
+      | bytestotal == 1 = replicate 6 padding
+      | otherwise = []
+
+-- | Provides methods for building a base64 system, with an option to toggle
+-- padding.
+mkBaseSystem64 :: String -> Maybe Char -> Alphabet -> BitwiseSystem
+mkBaseSystem64 name padchar abc =
+  BitwiseSystem name abc symbits groupbytes groupsymbols $
+    PaddingMethod <*> padImpl <$> padchar
+  where
+    groupbytes = 3
+    groupsymbols = 4
+    symbits = 6
+    padImpl padding bytestotal
+      | bytestotal > 3 = padImpl padding $ bytestotal `mod` groupbytes
+      | bytestotal == 2 = [padding]
+      | bytestotal == 1 = [padding, padding]
+      | otherwise = []
+
+-- | Defines the BaseSystem for binary. This could be a BitwiseSystem, but we
+-- would have to support multiple character ABCs.Symbols; currently we can't
+-- do this, because it depends on Text.chunksOf 1 to tokenize the utf8 codes.
+base2 :: RadixSystem
+base2 = RadixSystem "base2" ABCs.binary
+
+-- | Defines base10 as RadixSystem.
+base10 :: RadixSystem
+base10 = RadixSystem "base10" ABCs.decimal
+
+-- | Defines Bitcoin's base58 implementation. Flickr apparently has one too.
+base58btc :: RadixSystem
+base58btc = RadixSystem "base58btc" ABCs.btc58
+
+-- | Defines uppercase hexidecimal on BitwiseSystem. Orignally, this was on
+-- RadixSystem, but I believe BitwiseSystem can become the more optimized
+-- implementation. Either works.
+base16upper :: RadixSystem
+base16upper = RadixSystem "base16upper" ABCs.hexupper
+
+-- | Defines lowercase hexadecimal on BitwiseSystem.
+base16lower :: RadixSystem
+base16lower = RadixSystem "base16lower" ABCs.hexlower
+
+-- | Defines lowercase base32 from RFC4648, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-6
+base32lower :: BitwiseSystem
+base32lower = mkBaseSystem32 "base32lower" (Just '=') ABCs.b32lower
+
+-- | Defines lowercase base32 from RFC4648. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-6
+base32lowerNP :: BitwiseSystem
+base32lowerNP = mkBaseSystem32 "base32lowerNP" Nothing ABCs.b32lower
+
+-- | Defines uppercase base32 from RFC4648, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-6
+base32upper :: BitwiseSystem
+base32upper = mkBaseSystem32 "base32upper" (Just '=') ABCs.b32upper
+
+-- | Defines uppercase base32 from RFC4648. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-6
+base32upperNP :: BitwiseSystem
+base32upperNP = mkBaseSystem32 "base32upperNP" Nothing ABCs.b32upper
+
+-- | Defines lowercase base32 from RFC4648, extended hex version, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-7
+base32hexlower :: BitwiseSystem
+base32hexlower = mkBaseSystem32 "base32hexlower" (Just '=') ABCs.b32hexlower
+
+-- | Defines lowercase base32 from RFC4648, extended hex version. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-7
+base32hexlowerNP :: BitwiseSystem
+base32hexlowerNP = mkBaseSystem32 "base32hexlowerNP" Nothing ABCs.b32hexlower
+
+-- | Defines lowercase base32 from RFC4648, extended hex version, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-7
+base32hexupper :: BitwiseSystem
+base32hexupper = mkBaseSystem32 "base32hexupper" (Just '=') ABCs.b32hexupper
+
+-- | Defines uppercase base32 from RFC4648, extended hex version. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-7
+base32hexupperNP :: BitwiseSystem
+base32hexupperNP = mkBaseSystem32 "base32hexupperNP" Nothing ABCs.b32hexupper
+
+-- | Defines base64 from RFC4648, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-4
+base64 :: BitwiseSystem
+base64 = mkBaseSystem64 "base64" (Just '=') ABCs.b64
+
+-- | Defines base64 from RFC4648. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-4
+base64NP :: BitwiseSystem
+base64NP = mkBaseSystem64 "base64NP" Nothing ABCs.b64
+
+-- | Defines URL safe base64 from RFC4648, with padding.
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-5
+base64url :: BitwiseSystem
+base64url = mkBaseSystem64 "base64url" (Just '=') ABCs.b64url
+
+-- | Defines URL safe base64 from RFC4648. No padding!
+-- https://datatracker.ietf.org/doc/html/rfc4648.html#section-5
+base64urlNP :: BitwiseSystem
+base64urlNP = mkBaseSystem64 "base64urlNP" Nothing ABCs.b64url
