avi*_*ian 3 encryption postgresql
我想在StackOverflow上使用几次提到的pseudo_encrypt函数来使我的ID看起来更随机:https://wiki.postgresql.org/wiki/Pseudo_encrypt
如何自定义此选项以便为我输出唯一的"随机"数字.我在某处读到你可以改变1366.0常数,但我不想冒任何ID冒险,因为任何潜在的ID重复会导致重大问题.
我真的不知道每个常数实际上做了什么,所以除非我得到一些方向,否则我不想乱用它.有谁知道我可以安全地改变哪些常数?
这里是:
CREATE OR REPLACE FUNCTION "pseudo_encrypt"("VALUE" int) RETURNS int IMMUTABLE STRICT AS $function_pseudo_encrypt$
DECLARE
l1 int;
l2 int;
r1 int;
r2 int;
i int:=0;
BEGIN
l1:= ("VALUE" >> 16) & 65535;
r1:= "VALUE" & 65535;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
r1 := l2;
l1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::int << 16) + r1);
END;
$function_pseudo_encrypt$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
对于bigint的
CREATE OR REPLACE FUNCTION "pseudo_encrypt"("VALUE" bigint) RETURNS bigint IMMUTABLE STRICT AS $function_pseudo_encrypt$
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)::bigint;
r1 := l2;
l1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::bigint << 32) + r1);
END;
$function_pseudo_encrypt$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
替代解决方案:使用不同的密码
其他密码函数现在可以在postgres wiki上找到.它们会明显变慢,但除此之外,它们更适合生成定制的随机系列的独特数字.
对于32位输出,plpgsql中的Skip32将使用10字节宽的密钥加密其输入,因此您只需选择自己的密钥即可拥有自己的特定排列(2 ^ 32个唯一值的特定顺序将会出现).
对于64位输出,plpgsql中的XTEA将执行类似操作,但使用16字节宽的密钥.
否则,只需自定义pseudo_encrypt,请参阅以下内容:
关于pseudo_encrypt实施的解释:
此功能有3个属性
第一个和第二个属性来自Feistel网络,正如在@ CodesInChaos的答案中已经解释的那样,它们不依赖于这些常量的选择:1366还有150889和714025.
确保在更改时f(r1)它在数学意义上保持功能,这x=y意味着f(x)=f(y),或者换句话说,相同的输入必须始终产生相同的输出.打破这一点将打破这种独特性.
这些常数和这个公式的目的f(r1)是产生一个相当好的伪随机效应.使用postgres内置random()或类似的方法是不可能的,因为它不是如上所述的数学函数.
为什么这些任意常数?在这部分功能中:
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
Run Code Online (Sandbox Code Playgroud)
式和的值1366,150889和714025来自 在C数字食谱,第7章(1992年,由William H.Press,第2版):随机数,具体p.284和285.书不是在网络上直接可转位,但通过这里的界面可读:http://apps.nrbook.com/c/index.html.它也被引用作为实现PRNG的各种源代码的参考.
在本章讨论的算法中,上面使用的算法非常简单且相对有效.从前一个(jran)获取新的随机数的公式是:
jran = (jran * ia + ic) % im;
ran = (float) jran / (float) im; /* normalize into the 0..1 range */
Run Code Online (Sandbox Code Playgroud)
其中jran是当前的随机整数.
该发电机将必然遍历本身有一定数目的值(以下简称"期间"),所以常量后ia,ic并且im必须被仔细地选择该周期为尽可能地大.这本书提供了一个表p.285,其中建议了不同长度的常数.
ia=1366,ic=150889并且im=714025是2 29位期间的条目之一,这是不仅仅需要的方式.
最后乘以32767或2 15 -1不是PRNG的一部分,而是意味着从0..1伪随机浮点值产生正半整数.除非扩大算法的块大小,否则不要更改该部分.
| 归档时间: |
|
| 查看次数: |
1051 次 |
| 最近记录: |