我有一个16字节的md5哈希,我需要"折叠"使用XOR转换为4字节数据:{1st 4 bytes} XOR {2nd 4 bytes} XOR {3rd 4 bytes} XOR {4th 4 字节}。然后我需要将结果转换为Hex形式(8个字符串)。
我正在生成这样的哈希(解码为十六进制,因为它似乎更容易处理):
SELECT decode(md5('test'), 'hex');
但就我而言。我不知道将16字节散列分成4个4字节值的最佳方法,然后对这些4字节值进行异或。
答案 0 :(得分:0)
不幸的是,docs对于使用位字符串值可以做什么有点模糊,但提到了substring
函数(sytax在string functions page上),可以使用从中提取部分:
select i1 # i2 # i3 # i4
from cast('x' || md5('test') as bit(128)) bits,
cast(substring(bits from 97 for 32) as int4) i1,
cast(substring(bits from 65 for 32) as int4) i2,
cast(substring(bits from 33 for 32) as int4) i3,
cast(substring(bits from 1 for 32) as int4) i4
注意:低位在其位串表示中具有更高的索引,f.ex。
select 3::bit(32)
-- will yield '00000000000000000000000000000011'
答案 1 :(得分:0)
在花了一些时间理解this回答之后,我能够想出这个:
CREATE OR REPLACE FUNCTION compressed_md5(var_txt TEXT) RETURNS TEXT
AS $$
DECLARE
var_hash BYTEA;
var_compressedHash BYTEA;
var_offset INTEGER;
BEGIN
var_hash := decode(md5(var_txt), 'hex');
var_compressedHash := decode('00000000', 'hex'); -- prepopulate with some 4-byte data
FOR var_offset IN 0..3 LOOP
var_compressedHash := set_byte(var_compressedHash, var_offset,
get_byte(var_hash, var_offset) #
get_byte(var_hash, var_offset + 4) #
get_byte(var_hash, var_offset + 8) #
get_byte(var_hash, var_offset + 12));
END LOOP;
RETURN encode(var_compressedHash, 'hex');
END;
$$ LANGUAGE plpgsql;
SELECT compressed_md5('test');
结果:
"a35742cb"