--- Revision None +++ Revision 323731663237 @@ -0,0 +1,56 @@ +-module(mycaptcha). +-compile(export_all). + +-record(captcha, {key, value}). + +new() -> + CryptKey = crypto:rand_bytes(16), + + ok = try mnesia:dirty_write({captcha, 0, CryptKey}) + catch + _:_ -> + {atomic, ok} = mnesia:create_table(captcha, [{ram_copies, [node()]}, {attributes, record_info(fields, captcha)}]), + mnesia:dirty_write({captcha, 0, CryptKey}) + end, + + FileName = lists:flatmap(fun(Item) -> integer_to_list(Item) end, tuple_to_list(now())), + + Code = generate_rand(5), + + File = io_lib:format("/tmp/~s.png",[FileName]), + + Cmd = io_lib:format("convert -background 'none' -fill '#222222' -size 175 -gravity Center -wave 5x100 -swirl 50 -font DejaVu-Serif-Book -pointsize 28 label:~s -draw 'Bezier 10,40 50,35 100,35 150,35 200,50 250,35 300,35' ~s", [Code, File]), + os:cmd(Cmd), + + {ok, BinPng} = file:read_file(File), + file:delete(File), + + Sha = crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code), + CodeHex = mochihex:to_hex(Sha), + + {CodeHex, BinPng}. + +check(CodeHex, Code) -> + Sha = mochihex:to_bin(CodeHex), + [Rec] = mnesia:dirty_read({captcha, 0}), + CryptKey = Rec#captcha.value, + + case crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code) of + Sha -> + true; + + _ -> + false + end. + +generate_rand(Length) -> + Now = now(), + random:seed(element(1, Now), element(2, Now), element(3, Now)), + lists:foldl(fun(_I, Acc) -> [do_rand(0) | Acc] end, [], lists:seq(1, Length)). + +do_rand(R) when R > 46, R < 58; R > 64, R < 91; R > 96 -> +R; + +do_rand(_R) -> + %do_rand(48 + random:uniform(74)). %% exluding zero + do_rand(47 + random:uniform(75)).