История изменений
Исправление Toxo2, (текущая версия) :
Программа пишется в несколько строчек на Питоне
Что-то никто тут свой велосипед в несколько строчек не показал.
Вот такое у меня получилось. Проверил, работает.
CREATE OR REPLACE FUNCTION public.topt(p_key text)
RETURNS text
LANGUAGE plpgsql
AS $function$
DECLARE
v_hmac bytea;
v_offset int;
v_res int4;
BEGIN
v_hmac :=
hmac(
/* получаем текущий номер 30 секундного отрезка
* в 16ричном виде, строкой на 16 символов */
format(
'\x%s'
,lpad(
to_hex(
floor(extract(epoch FROM now()) / 30)::int
), 16, '0'
)
)::bytea,
/* декодируем входной секретный ключ по base32 */
util_base32_decode(p_key),
/* и хмакаем всё это по алгоритму sha1 */
'sha1'
)
;
/* такая вот магия определения смещения начала нужных 4х байтов
* видимо надо взять значение последних 4 битов от HMAC */
v_offset := get_byte(v_hmac, length(v_hmac) - 1) & 0x0F;
/* теперь собираем в int4 нужные 4 байта от смещения
* а у первого байта сбрасываем старший бит */
v_res :=
((get_byte(v_hmac, 0 + v_offset) << 24) & 0x7F000000)
|
(get_byte(v_hmac, 1 + v_offset) << 16)
|
(get_byte(v_hmac, 2 + v_offset) << 8)
|
(get_byte(v_hmac, 3 + v_offset))
;
/* возвращаем остаток от деления на 1 000 000
* дополнив слева нулями до 6 символов */
RETURN lpad((v_res % 1000000)::text, 6, '0');
END;
$function$
;
Кто не умеет в велосипеды - те просто пользователЯ :P
Исправление Toxo2, :
Программа пишется в несколько строчек на Питоне
Что-то никто тут свой велосипед в несколько строчек не показал.
Вот такое у меня получилось. Проверил, работает.
CREATE OR REPLACE FUNCTION public.topt(p_key text)
RETURNS text
LANGUAGE plpgsql
AS $function$
DECLARE
v_hmac bytea;
v_offset int;
v_res int4;
BEGIN
v_hmac :=
hmac(
/* получаем текущий номер 30 секундного отрезка
* в 16ричном виде, строкой на 16 символов */
format(
'\x%s'
,lpad(
to_hex(
floor(extract(epoch FROM now()) / 30)::int
), 16, '0'
)
)::bytea,
/* декодируем входной секретный ключ по base32 */
util_base32_decode(p_key),
/* и хмакаем всё это по алгоритму sha1 */
'sha1'
)
;
/* такая вот магия определения смещения начала нужных 4х байтов
* видимо надо взять значение последних 4 битов от HMAC */
v_offset := get_byte(v_hmac, length(v_hmac) - 1) & 0x0F;
/* теперь собираем в int4 нужные 4 байта от смещения
* а у первого байта сбрасываем старший бит */
v_res :=
((get_byte(v_hmac, 0 + v_offset) << 24) & 0x7F000000)
|
(get_byte(v_hmac, 1 + v_offset) << 16)
|
(get_byte(v_hmac, 2 + v_offset) << 8)
|
(get_byte(v_hmac, 3 + v_offset))
;
/* возвращаем остаток от деления на 1 000 000
* дополнив слева нулями до 6 символов */
RETURN lpad((v_res % 1000000)::text, 6, '0');
END;
$function$
;
Кто не умеет в велосипеды - те просто пользователя :P
Исправление Toxo2, :
Программа пишется в несколько строчек на Питоне
Что-то никто тут свой велосипед в несколько строчек не показал.
Вот такое у меня получилось. Проверил, работает.
CREATE OR REPLACE FUNCTION public.topt(p_key text)
RETURNS text
LANGUAGE plpgsql
AS $function$
DECLARE
v_hmac bytea;
v_offset int;
v_res int4;
BEGIN
v_hmac :=
hmac(
/* получаем текущий номер 30 секундного отрезка
* в 16ричном виде, строкой на 16 символов */
format(
'\x%s'
,lpad(
to_hex(
floor(extract(epoch FROM now()) / 30)::int
), 16, '0'
)
)::bytea,
/* декодируем входной секретный ключ по base32 */
util_base32_decode(p_key),
/* и хмакаем всё это по алгоритму sha1 */
'sha1'
)
;
/* такая вот магия определения смещения начала нужных 4х байтов
* видимо надо взять значение последних 4 битов от HMAC */
v_offset := get_byte(v_hmac, length(v_hmac) - 1) & 0x0F;
/* теперь собираем в int4 нужные 4 байта от смещения
* а у первого байта сбрасываем старший бит */
v_res :=
((get_byte(v_hmac, 0 + v_offset) << 24) & 0x7F000000)
|
(get_byte(v_hmac, 1 + v_offset) << 16)
|
(get_byte(v_hmac, 2 + v_offset) << 8)
|
(get_byte(v_hmac, 3 + v_offset))
;
/* возвращаем остаток от деления на 1 000 000
* дополнив слева нулями до 6 символов */
RETURN lpad((v_res % 1000000)::text, 6, '0');
END;
$function$
;
Исходная версия Toxo2, :
Программа пишется в несколько строчек на Питоне
Что-то никто тут свой велосипед в несколько строчек не показал.
Вот такое у меня получилось. Проверил, работает.
CREATE OR REPLACE FUNCTION public.topt(p_key text)
RETURNS text
LANGUAGE plpgsql
AS $function$
DECLARE
v_hmac bytea;
v_offset int;
v_res int4;
BEGIN
v_hmac :=
hmac(
/* получаем текущий номер 30 секундного отрезка
* в 16ричном виде, строкой на 16 символов */
format(
'\x%s'
,lpad(
to_hex(
floor(extract(epoch FROM now()) / 30)::int
), 16, '0'
)
)::bytea,
/* декодируем входной секретный ключ по base32 */
util_base32_decode(p_key),
/* и хмакаем всё это по алгоритму sha1 */
'sha1'
)
;
/* такая вот магия определения смещения начала нужных 4х байтов
* видимо надо взять значение последних 4 битов от HMAC */
v_offset := get_byte(v_hmac, length(v_hmac) - 1) & 0x0F;
/* теперь собираем в int4 нужные 4 байта от смещения
* а у первого байта сбрасываем старший бит */
v_res :=
((get_byte(v_hmac, 0 + v_offset) << 24) & 0x7F000000)
|
(get_byte(v_hmac, 1 + v_offset) << 16)
|
(get_byte(v_hmac, 2 + v_offset) << 8)
|
(get_byte(v_hmac, 3 + v_offset))
;
/* возвразаем остаток от деления на 1 000 000
* дополнив слева нулями до 6 символов */
RETURN lpad((v_res % 1000000)::text, 6, '0');
END;
$function$
;