How to XOR md5 hash values and cast them to HEX in postgresql

回眸只為那壹抹淺笑 提交于 2019-12-06 14:15:21

Those binary values are in fact of type bit varying, which differs significantly from bytea.

bit varying comes with built-in support for XOR and such, but PostgreSQL doesn't provide a cast from bit varying to bytea.

You could write a function that does the cast, but it's not trivial and probably not the more efficient way in your case.

It would make more sense to XOR the md5 digests directly. PostgreSQL doesn't provide the XOR operator for bytea either, but it can be easily written in a function, especially when assumed that the operands have an equal length (16 bytes in the case of md5 digests):

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;

Now the built-in postgresql md5 function that produces an hex string is not the best fit for post-processing, either. The pgcrypto module provides this function instead:

 digest(data text, type text) returns bytea

Using this function and getting the final result as an hex string:

   select encode(
          xor_digest ( digest('first string', 'md5') ,
                       digest('second string', 'md5')),
          'hex');

produces the result: c1bd61a3c411bc0127c6d7ab1238c4bd with type text.

If pgcrypto can't be installed and only the built-in md5 function is available, you could still combine encode and decode to achieve the result like this:

select
encode(
 xor_digest(
   decode(md5('first string'), 'hex'),
   decode(md5('second string'), 'hex')
 ),
 'hex'
);

Result:

c1bd61a3c411bc0127c6d7ab1238c4bd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!