In the game Factorio there are string-encoded representations of blueprints that I wish to decode.
The implementation according to their wiki is the following:
This is a technical description of the blueprint string format, used to share blueprints with other users.
A blueprint string is a json representation of the blueprint, encoded using base 64 with the version byte in front (0 in vanilla 0.15) and then compressed with zlib deflate. So to get the json representation of a blueprint from a blueprint string, skip the first byte, base64 decode the string, and finally decompress using zlib deflate.
Please keep in mind that I am very new to Haskell, having only played around with it maybe once earlier in my life, though I do have some functional programming experience.
The list of dependencies is the following:
- base >= 4.7 && < 5
- bytestring
- base64-bytestring
- zlib
The Main.hs
file:
module Main where
import Lib
import System.Environment
main :: IO ()
main = do
args <- getArgs
if null args
then putStrLn "Usage: factorio-exe <blueprint-string>"
else putStrLn (blueprintJson (head args))
The Lib.hs
file:
module Lib
( blueprintJson
) where
import Codec.Compression.Zlib
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy.Char8 as L
import Data.ByteString.Base64
blueprintJson :: [Char] -> [Char]
blueprintJson str = bpDeflate (bpDecode str)
bpDecode :: [Char] -> C.ByteString
bpDecode str = let (Right decoded) = decode (C.pack (tail str)) in decoded
bpDeflate :: C.ByteString -> [Char]
bpDeflate bstr = L.unpack (decompress (L.fromStrict bstr))
An example blueprint string to test with is the following:
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
Do note that when decoding that there may appear characters with which the Windows Command Prompt may have issues displaying.