我需要将存储在我的数据库中的字符串转换为数字值。结果可以是Integer(首选)或Bigint。此转换将在PL / pgSQL函数的数据库端完成。
有人可以指点一些算法或任何可用于实现此目的的API吗?
我一直在Google上搜索这几个小时,到目前为止找不到任何有用的东西:(
答案 0 :(得分:40)
保留MD5哈希的前32位或64位。当然,它会使md5的主要属性(=碰撞概率无穷小)无效,但你仍然会得到一个广泛的值分散,这可能足以解决你的问题。
从其他答案派生的SQL函数:
对于bigint:
create function h_bigint(text) returns bigint as $$
select ('x'||substr(md5($1),1,16))::bit(64)::bigint;
$$ language sql;
对于int:
create function h_int(text) returns int as $$
select ('x'||substr(md5($1),1,8))::bit(32)::int;
$$ language sql;
答案 1 :(得分:13)
您可以毫无问题地创建md5哈希值:
select md5('hello, world');
返回一个十六进制数的字符串。
不幸的是,没有内置函数可以将十六进制转换为整数,但是无论如何你都是在PL / pgSQL中这样做,这可能会有所帮助:
答案 2 :(得分:4)
必须是整数吗? pg_crypto模块提供了许多标准哈希函数(md5,sha1等)。它们都返回bytea。我想你可以扔掉一些比特并将bytea转换成整数。
bigint太小,无法存储加密哈希。 pg支持的最大非bytea二进制类型是uuid。您可以像这样向uuid投射摘要:
select ('{'||encode( substring(digest('foobar','sha256') from 1 for 16), 'hex')||'}')::uuid;
uuid
--------------------------------------
c3ab8ff1-3720-e8ad-9047-dd39466b3c89
答案 3 :(得分:0)
这是Java String.hashCode()
的实现:
CREATE OR REPLACE FUNCTION hashCode(_string text) RETURNS INTEGER AS $$
DECLARE
val_ CHAR[];
h_ INTEGER := 0;
ascii_ INTEGER;
c_ char;
BEGIN
val_ = regexp_split_to_array(_string, '');
FOR i in 1 .. array_length(val_, 1)
LOOP
c_ := (val_)[i];
ascii_ := ascii(c_);
h_ = 31 * h_ + ascii_;
raise info '%: % = %', i, c_, h_;
END LOOP;
RETURN h_;
END;
$$ LANGUAGE plpgsql;