-module(qrbg). % Include preset username/password -include_lib("qrbg.hrl"). % % API % -export([connect/0, get_response/1, get_response/3, extract_data/1]). -export([extract_int/1, extract_unsigned_int/1, extract_short_int/1, extract_unsigned_short_int/1, extract_long_int/1, extract_unsigned_long_int/1]). -export([extract_byte/1, extract_char/1, extract_float/1, extract_unsigned_float/1, extract_double/1, extract_unsigned_double/1]). -export([extract_int/2, extract_bytes/2]). -export([rand_bytes/1]). connect() -> gen_tcp:connect("random.irb.hr", 1227, [binary, {packet, 0}]). get_response(Socket) -> get_response(Socket, ?USERNAME, ?PASSWORD). get_response(Socket, Username, Password) -> ContentLength = length(Username) + length(Password) + 6, UsernameLength = length(Username), PasswordLength = length(Password), Data = list_to_binary([<<0:8,ContentLength:16,UsernameLength:8>>, Username, <>, Password, <>]), ok = gen_tcp:send(Socket, Data), % TODO: handle error conditions process_data(Socket, []). extract_data(Bin) -> <> = Bin, % io:format("Response: ~w Reason: ~w Length: ~w Data: ~w~n", [Response, Reason, Length, Data]), {ok, Response, Reason, Length, Data}. % Various data extraction bits extract_int(Bin) -> <> = Bin, {Int, Rest}. extract_unsigned_int(Bin) -> <> = Bin, {UnsignedInt, Rest}. extract_short_int(Bin) -> <> = Bin, {ShortInt, Rest}. extract_unsigned_short_int(Bin) -> <> = Bin, {UnsignedShortInt, Rest}. extract_long_int(Bin) -> <> = Bin, {LongInt, Rest}. extract_unsigned_long_int(Bin) -> <> = Bin, {UnsignedLongInt, Rest}. extract_byte(Bin) -> <> = Bin, {Byte, Rest}. extract_char(Bin) -> extract_byte(Bin). % TODO: Fix float/double functions extract_float(Bin) -> % Python: data = 0x3F800000 | (self.getInt() & 0x00FFFFFF) <> = Bin, {Float, Rest}. extract_unsigned_float(Bin) -> <> = Bin, {UnsignedFloat, Rest}. extract_double(Bin) -> % Python: data = 0x3FF0000000000000l | (self.getLong() & 0x000FFFFFFFFFFFFFl); <> = Bin, {Double, Rest}. extract_unsigned_double(Bin) -> <> = Bin, {UnsignedDouble, Rest}. % Not included in Python/C libs extract_int(Bin, Length) -> <> = Bin, {Int, Rest}. extract_bytes(Bin, Length) -> <> = Bin, {Bytes, Rest}. % % crypto compatability API % rand_bytes(Number) -> {ok, Socket} = connect(), Response = get_response(Socket), {ok, _Response, _Reason, _Length, Data} = extract_data(Response), {Bytes, _Rest} = extract_bytes(Data, Number), Bytes. % % Internal % process_data(Socket, SoFar) -> receive {tcp, Socket, Bin} -> process_data(Socket, [Bin|SoFar]); {tcp_closed, Socket} -> list_to_binary(lists:reverse(SoFar)) end.