Эти двоичные значения на самом деле относятся к типу bit varying
, который значительно отличается от bytea
.
bit varying
поставляется со встроенной поддержкой XOR и т. д., но PostgreSQL не обеспечивает приведение от bit varying
к bytea
.
Вы можете написать функцию, которая выполняет приведение, но это не тривиально и, вероятно, не более эффективно в вашем случае.
Было бы более разумно напрямую использовать XOR для дайджестов md5. PostgreSQL также не предоставляет оператора XOR для bytea
, но его можно легко записать в функцию, особенно если предположить, что операнды имеют одинаковую длину (16 байт в случае дайджестов md5):
CREATE FUNCTION xor_digests(_in1 bytea, _in2 bytea) RETURNS bytea
AS $$
DECLARE
o int; -- offset
BEGIN
FOR o IN 0..octet_length(_in1)-1 LOOP
_in1 := set_byte(_in1, o, get_byte(_in1, o) # get_byte(_in2, o));
END LOOP;
RETURN _in1;
END;
$$ language plpgsql;
Теперь встроенная функция postgresql md5
, которая создает шестнадцатеричную строку, также не очень подходит для постобработки. Вместо этого модуль pgcrypto
предоставляет следующую функцию:
digest(data text, type text) returns bytea
Использование этой функции и получение конечного результата в виде шестнадцатеричной строки:
select encode(
xor_digest ( digest('first string', 'md5') ,
digest('second string', 'md5')),
'hex');
выдает результат: c1bd61a3c411bc0127c6d7ab1238c4bd
с типом text
.
Если pgcrypto
не может быть установлен и доступна только встроенная функция md5
, вы все равно можете комбинировать encode
и decode
для достижения такого результата:
select
encode(
xor_digest(
decode(md5('first string'), 'hex'),
decode(md5('second string'), 'hex')
),
'hex'
);
Результат:
c1bd61a3c411bc0127c6d7ab1238c4bd
person
Daniel Vérité
schedule
20.07.2013