sql - plpgsql 中采用 bigint 的 pseudo_encrypt() 函数

标签 sql postgresql plpgsql

我正在开发一个生成随机 ID 的系统,就像答案 #2 here 中一样.

我的问题是,提到的 pseudo_encrypt()函数适用于 int 而不是 bigint。我试图重写它,但它总是返回相同的结果:

CREATE OR REPLACE FUNCTION pseudo_encrypt(VALUE bigint) returns bigint AS $$
DECLARE
l1 bigint;
l2 int;
r1 bigint;
r2 int;
i int:=0;
BEGIN
    l1:= (VALUE >> 32) & 4294967296::bigint;
    r1:= VALUE & 4294967296;
    WHILE i < 3 LOOP
        l2 := r1;
        r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
        l1 := l2;
        r1 := r2;
        i := i + 1;
    END LOOP;
RETURN ((l1::bigint << 32) + r1);
END;
$$ LANGUAGE plpgsql strict immutable;

有人可以检查一下吗?

最佳答案

4294967295 必须用作位掩码以选择 32 位(而不是 4294967296)。 这就是为什么目前您对不同输入获得相同值的原因。

我还建议对 l2r2 类型使用 bigint,它们与 r1 应该没有什么区别l1

并且,为了更好的随机性,在 PRNG 函数中使用更高的乘数来获得真正占用 32 位的中间 block ,例如 32767*32767 而不是 32767。

完整修改版:

CREATE OR REPLACE FUNCTION pseudo_encrypt(VALUE bigint) returns bigint AS $$
DECLARE
l1 bigint;
l2 bigint;
r1 bigint;
r2 bigint;
i int:=0;
BEGIN
    l1:= (VALUE >> 32) & 4294967295::bigint;
    r1:= VALUE & 4294967295;
    WHILE i < 3 LOOP
        l2 := r1;
        r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767*32767)::int;
        l1 := l2;
        r1 := r2;
        i := i + 1;
    END LOOP;
RETURN ((l1::bigint << 32) + r1);
END;
$$ LANGUAGE plpgsql strict immutable;

第一个结果:

select x,pseudo_encrypt(x::bigint) from generate_series (1, 10) as x;
 x  |   pseudo_encrypt    
----+---------------------
  1 | 3898573529235304961
  2 | 2034171750778085465
  3 |  169769968641019729
  4 | 2925594765163772086
  5 | 1061193016228543981
  6 | 3808195743949274374
  7 | 1943793931158625313
  8 |   88214277952430814
  9 | 2835217030863818694
 10 |  970815170807835400
(10 rows)

关于sql - plpgsql 中采用 bigint 的 pseudo_encrypt() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12761346/

相关文章:

SQL (Postgres) 函数定义 - 返回

mysql - 删除除一个优化查询之外的所有重复项

SQLite:确定字符串的任何部分是否包含选择查询返回的任何一个(多个)字符串

postgresql - Postgres - 将行移动到不同的表

sql - Pl/PgSQL,插入两个表,一个有标题行

postgresql - 奇怪的 now() 与 Postgres 触发器的时差

sql - 执行按位求和

java - 使用文本字段插入数据很困难(jdbc swing)

perl - 如何使用 Perl、DBI 和占位符插入到 PostgreSQL 中?

java - 在 Heroku 上获取 java.lang.ClassNotFoundException : j ava. time.temporal.TemporalField