在Postgresql中生成具有固定长度的唯一随机数
我需要在Postgresql中生成固定长度为13位的唯一随机数.
我发现了一个类似的 thread,其中使用了使用“pseudo_encrypt”加密的序列,但返回的数字没有固定的长度. 所以,我需要的是:得到一个固定长度为13位的加密随机序列,其中最小值为0000000000001,最大值为9999999999999. 可能吗?如果从前面的零开始是不可能的不是一个大问题(我认为),我可以在从数据库读取时以编程方式设置它们,但如果Postgresql可以自己完成它将会很好. – 编辑 – 在实现了一些有用的东西后,我必须改变问题,以便更好地解释我需要的东西: 我需要在Postgresql中生成唯一的随机数(bigint),最大长度为13位.实际上我正在尝试使用pseudo_encrypt函数(64位),但返回的数字显然不是固定的最大长度为13,在32位情况下,最大长度是10位(int),而对于64位是19(bigint). 那么,如何获得一个固定最大长度为13位的加密随机序列,其中最小值为1,最大值为9999999999999? 是否可以修改64位pseudo_ecrypt函数以获得此结果?或者,如果不可能,还有其他方法可以获得具有此要求的唯一序列吗? 伪加密功能(64位) 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;
调整现有函数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); END; $$LANGUAGE plpgsql strict immutable; 输入必须小于(2 ^ 42)-1,否则输出将发生冲突,如pseudo_encrypt42(x)= pseudo_encrypt42(x mod 2 ^ 42). 关于2 ^ 42和10 ^ 13之间缺失数字可以做些什么? 2 ^ 42 – 10 ^ 13 = 5601953488896因此缺少相当多的数字. 另一组可以通过相同的函数获得,只需添加偏移量即可. 4398046511104 pseudo_encrypt42(x)保证在4398046511104和2 * 4398046511104 = 8796093022208之间的唯一值,以便更接近目标.相同的技术可以应用于其他几个范围,甚至不一定具有相同的尺寸. 但是,这种解决方法会降低随机行为,因为不是每个数字都在0到X之间的单个输出范围,而是获得N个不同的X / N数字输出范围.有了这样的几个不同的分区,很容易猜到输出的分区,而不是分区内的值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |