Skip to content

Instantly share code, notes, and snippets.

@Jim-Holmstroem
Last active March 5, 2017 22:45
Show Gist options
  • Save Jim-Holmstroem/96df62ad70a9abe121b0590fdd08f8e7 to your computer and use it in GitHub Desktop.
Save Jim-Holmstroem/96df62ad70a9abe121b0590fdd08f8e7 to your computer and use it in GitHub Desktop.
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log, logShow)
import Control.Monad.Except
import Math (sqrt)
import Control.Plus (empty)
import Control.MonadZero (guard)
import Data.Array ((:))
import Data.Traversable (sequence, foldl)
import Data.Maybe (Maybe(..), fromMaybe, fromJust)
import Data.Int
import Data.Int.Bits (xor)
import Data.String
import Data.Generic
import Data.Foreign ( F
, ForeignError
, unsafeFromForeign
, writeObject
)
import Data.Foreign.Generic
import Data.Foreign.Generic.Types
import Data.Foreign.Class ( class AsForeign
, class IsForeign
, readJSON
, readProp
, (.=)
, write
)
import Control.Monad.Except (runExcept)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Aff (launchAff)
import Data.Either (Either(..))
import Data.HTTP.Method (Method(..))
import Network.HTTP.Affjax (get, post, affjax, defaultRequest)
import Browser.WebStorage (localStorage, getItem, setItem, removeItem)
fromHex :: String -> Maybe Int
fromHex = fromStringAs hexadecimal
toHex :: Int -> String
toHex = toStringAs hexadecimal
bytes :: String -> Array (Maybe Int)
bytes "" = empty
bytes str = fromHex (take 2 str) : bytes (drop 2 str)
port :: String
port = "5000"
solve :: String -> Maybe String
solve = map (joinWith "" <<< map (toHex <<< xor 42)) <<< sequence <<< bytes
-- TODO(jim) validate with purescript-validate module
-- TODO(jim) use generics for decode/encode to remove boilerplate
data Challenge = Challenge { challenge :: String
}
derive instance genericChallenge :: Generic Challenge
instance showChallenge :: Show Challenge where
show = gShow
instance asForeignChallenge :: AsForeign Challenge where
write (Challenge challenge) = writeObject [ "challenge" .= challenge.challenge
]
instance isForeignChallenge :: IsForeign Challenge where
read value = do
challenge <- readProp "challenge" value
pure $ Challenge { challenge: challenge }
data Answer = Answer { product :: String
, version :: Int
, challenge_id :: String
, answer :: String
}
derive instance genericAnswer :: Generic Answer
instance showAnswer :: Show Answer where
show = gShow
instance asForeignAnswer :: AsForeign Answer where
write (Answer answer) = writeObject [ "product" .= answer.product
, "version" .= answer.version
, "challenge_id" .= answer.challenge_id
, "answer" .= answer.answer
]
instance isForeignAnswer :: IsForeign Answer where
read value = do
product <- readProp "product" value
version <- readProp "version" value
challenge_id <- readProp "challenge_id" value
answer <- readProp "answer" value
pure $ Answer { product: product
, version: version
, challenge_id: challenge_id
, answer: answer
}
data TokenState = TokenState { count :: Int
, token :: String
}
derive instance genericTokenState :: Generic TokenState
instance showTokenState :: Show TokenState where
show = gShow
instance asForeignTokenState :: AsForeign TokenState where
write (TokenState tokenState) = writeObject [ "count" .= tokenState.count
, "token" .= tokenState.token
]
instance isForeignTokenState :: IsForeign TokenState where
read value = do
count <- readProp "count" value
token <- readProp "token" value
pure $ TokenState { count: count
, token: token
}
defaultTokenState = TokenState { count: 0
, token: ""
}
storage = localStorage
getStorage = getItem localStorage
setStorage = setItem localStorage
getTokenState = do
tokenStateSerialized <- getStorage "tokenState"
pure $ case tokenStateSerialized of
(Just tokenStateSerialized) -> runExcept $ readJSON tokenStateSerialized :: F TokenState
Nothing -> Right defaultTokenState
setTokenState tokenState = do
tokenStateSerialized <- unsafeFromForeign <<< write $ tokenState
setStorage tokenStateSerialized
main = do
logShow defaultTokenState
token <- getTokenState
logShow token
logShow $ runExcept $ readJSON """{"challenge": "00"}""" :: F Challenge
--log $ unsafeFromForeign $ write $ Challenge { challenge: "00" }
--main = launchAff $ do
-- res <- get $ "http://localhost:" <> port <> "/v1/challenge?p=product&v=1"
-- liftEff $ logShow $ runExcept (readJSON res.response :: F Challenge)
--main = do
-- log <<< show $ solve "deadbeef"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment