Files
simplex-manager/bots/haskell/simplexxx-directory/src/Directory/Captcha.hs
Jon 5c80ac310f Initial commit: bots, AI-parameterised support bot, web frontend
- simplex-deadmans-bot: Dead Man's Switch Haskell bot
- simplexxx-directory: private SimpleXXX directory bot (fork of simplex-directory-service)
- simplex-support-bot: support triage bot with configurable AI backend
  - --ai-url and --ai-model flags for any OpenAI-compatible provider
  - works with Grok, Ollama, OpenAI, LM Studio, etc.
  - AI_API_KEY env var (GROK_API_KEY still accepted as alias)
- web: SimpleXXX directory frontend (Groups/Channels tabs, matches simplex.chat/directory style)
- manager/: placeholder for Python profile manager (coming soon)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 00:39:08 +01:00

38 lines
1.1 KiB
Haskell

module Directory.Captcha (getCaptchaStr, matchCaptchaStr) where
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import System.Random (randomRIO)
getCaptchaStr :: Int -> String -> IO String
getCaptchaStr 0 s = pure s
getCaptchaStr n s = do
i <- randomRIO (0, length captchaChars - 1)
let c = captchaChars !! i
getCaptchaStr (n - 1) (c : s)
where
captchaChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
matchCaptchaStr :: T.Text -> T.Text -> Bool
matchCaptchaStr captcha guess = T.length captcha == T.length guess && matchChars (T.zip captcha guess)
where
matchChars [] = True
matchChars ((c, g) : cs) = matchChar c == matchChar g && matchChars cs
matchChar c = fromMaybe c $ M.lookup c captchaMatches
captchaMatches =
M.fromList
[ ('0', 'O'),
('1', 'I'),
('c', 'C'),
('l', 'I'),
('o', 'O'),
('p', 'P'),
('s', 'S'),
('u', 'U'),
('v', 'V'),
('w', 'W'),
('x', 'X'),
('z', 'Z')
]