Created
September 6, 2023 03:19
-
-
Save manveru/74eb41d850bc146b7e78c4cb059507e2 to your computer and use it in GitHub Desktop.
Encode to base 64 in pure Nix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{lib, ...}: { | |
toBase64 = text: let | |
inherit (lib) sublist mod stringToCharacters concatMapStrings; | |
inherit (lib.strings) charToInt; | |
inherit (builtins) substring foldl' genList elemAt length concatStringsSep stringLength; | |
lookup = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
sliceN = size: list: n: sublist (n * size) size list; | |
pows = [(64 * 64 * 64) (64 * 64) 64 1]; | |
intSextets = i: map (j: mod (i / j) 64) pows; | |
compose = f: g: x: f (g x); | |
intToChar = elemAt lookup; | |
convertTripletInt = sliceInt: concatMapStrings intToChar (intSextets sliceInt); | |
sliceToInt = foldl' (acc: val: acc * 256 + val) 0; | |
convertTriplet = compose convertTripletInt sliceToInt; | |
join = concatStringsSep ""; | |
convertLastSlice = slice: let | |
len = length slice; | |
in | |
if len == 1 | |
then (substring 0 2 (convertTripletInt ((sliceToInt slice) * 256 * 256))) + "==" | |
else if len == 2 | |
then (substring 0 3 (convertTripletInt ((sliceToInt slice) * 256))) + "=" | |
else ""; | |
len = stringLength text; | |
nFullSlices = len / 3; | |
bytes = map charToInt (stringToCharacters text); | |
tripletAt = sliceN 3 bytes; | |
head = genList (compose convertTriplet tripletAt) nFullSlices; | |
tail = convertLastSlice (tripletAt nFullSlices); | |
in | |
join (head ++ [tail]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment