gpt4 book ai didi

postgresql - 如何自定义 Postgres 伪加密函数的输出?

转载 作者:行者123 更新时间:2023-11-29 11:39:07 26 4
gpt4 key购买 nike

我想使用 StackOverflow 上多次提到的伪加密函数让我的 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;

对于 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;

最佳答案

替代方案:使用不同的密码

其他密码函数现在可以在 postgres wiki 上找到。它们的速度会明显变慢,但除此之外,它们更适合生成定制的随机外观系列唯一数字。

对于 32 位输出,Skip32 in plpgsql将使用 10 字节宽的 key 对其输入进行加密,因此您只需选择自己的 key 即可拥有自己的特定排列(2^32 个唯一值将出现的特定顺序)。

对于 64 位输出,XTEA in plpgsql将做类似的事情,但使用 16 字节宽的 key 。

否则,只自定义pseudo_encrypt,见下文:

关于pseudo_encrypt实现的解释:

这个函数有3个属性

  • 输出值的全局唯一性
  • 可逆性
  • 伪随机效应

第一个和第二个属性来自 Feistel 网络,正如在@CodesInChaos 的回答中已经解释的那样,它们不依赖于这些常量的选择:1366150889714025

确保在更改 f(r1) 时它保持数学意义上的函数,即 x=y 意味着 f(x)=f (y),换句话说,相同的输入必须始终产生相同的输出。打破这一点会破坏唯一性。

f(r1) 这些常量和这个公式的目的是产生相当好的伪随机效应。使用 postgres 内置 random() 或类似方法是不可能的,因为它不是上述的数学函数。

为什么是这些任意常量?在这部分函数中:

r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;

公式和值 1366150889714025 来自 Numerical recipes in C (1992, William H.Press,第 2 版),第 7 章:随机数,特别是第 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 */

其中jran是当前的随机整数。

这个生成器必然会在一定数量的值(“周期”)之后循环自身,所以常量 iaicim 必须仔细选择那个时期尽可能大。该书提供了一个表 p.285,其中针对不同的周期长度建议了常量。

ia=1366, ic=150889im=714025 是一个时期的条目之一 229 位,远远超过所需。

最后,乘以 32767 或 215-1 不是 PRNG 的一部分,而是要从 0..1 伪-1 产生正半整数随机浮点值。不要更改该部分,除非要扩大算法的 block 大小。

关于postgresql - 如何自定义 Postgres 伪加密函数的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30689021/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com