调整现有函数N< 64位值 调整bigint变量以将输出减少到2 ^ N值相对简单,其中N是偶数,并且小于64. 要获得13位十进制数,请考虑2 ^ N具有13位数的最大N.那是N = 42,其中2 ^ 42 = 4398046511104. 该算法通过将输入值分成具有相同位数的两半来工作,并使它们流过Feistel网络,基本上与舍入函数的结果进行异或,并在每次迭代时交换一半. 如果在该过程的每个阶段,每一半都限制为21位,则结合两半的结果保证不超过42位. 所以这是我提出的变体:
CREATE OR REPLACE FUNCTION pseudo_encrypt42(VALUE bigint) returns bigint
AS $$
DECLARE
l1 bigint;
l2 bigint;
r1 bigint;
r2 bigint;
i int:=0;
b21 int:=(1<<21)-1; -- 21 bits mask for a half-number => 42 bits total
BEGIN
l1:= VALUE >> 21;
r1:= VALUE & b21;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # (((((1366*r1+150889)%714025)/714025.0)*32767*32767)::int & b21);
l1 := l2;
r1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::bigint << 21) + r1);