[SQL] BIGINT 소요 pseudo_encrypt () 함수 plpgsql
SQLBIGINT 소요 pseudo_encrypt () 함수 plpgsql
여기 대답 # 2에서와 같이 임의 ID를 생성하는 시스템에서 일하고 있어요.
내 문제는 INT와 상술 pseudo_encrypt () 함수가 작동하는 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;
누군가가이를 확인할 수 있습니까?
해결법
-
==============================
1.4294967295은 (4294967296 대신의) 32 개 비트를 선택하기 위해 비트 마스크로 사용되어야한다. 즉 현재 서로 다른 입력에 대해 동일한 값을받을 이유입니다.
4294967295은 (4294967296 대신의) 32 개 비트를 선택하기 위해 비트 마스크로 사용되어야한다. 즉 현재 서로 다른 입력에 대해 동일한 값을받을 이유입니다.
나는 또한 L2와 R2의 유형 BIGINT를 사용하는 것이 좋습니다 것, 그들은 정말 R1과 L1에서 차이가한다
그리고, 더 나은 임의성에 대한, 정말 32 비트를 차지합니다 32767 * 32767 대신 32767과 같은 중간 블록을 얻기 위해 PRNG 기능에 훨씬 더 높은 배율을 사용합니다.
전체 수정 된 버전 :
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)
-
==============================
2.올드하지만 여전히 흥미로운 질문입니다. 다니엘스에 비교하는 것은 내가 약간 수정 된 버전을 사용하여이에 return 문을 변경하고 대답으로도 기사 의사의 암호화의 끝 부분에 언급 한 (교환 R1과 L1) :
올드하지만 여전히 흥미로운 질문입니다. 다니엘스에 비교하는 것은 내가 약간 수정 된 버전을 사용하여이에 return 문을 변경하고 대답으로도 기사 의사의 암호화의 끝 부분에 언급 한 (교환 R1과 L1) :
RETURN ((r1::bigint << 32) + l1);
이러한 변화의 이유는 기본 파이 스텔 알고리즘은 마지막 라운드의 끝에 좌우 교환하지해야한다는 것입니다. 이러한 변화와 함께 함수는 자신의 역 기능의 역할을 할 수있는 능력을 회복 :
pseudo_encrypt(pseudo_encrypt(x) == x // always returns true
여기를 pgsql의 전체 코드는 다음과 같습니다
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 ((r1::bigint << 32) + l1); END; $$ LANGUAGE plpgsql strict immutable;
from https://stackoverflow.com/questions/12761346/pseudo-encrypt-function-in-plpgsql-that-takes-bigint by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 오라클에서 각 그룹에 대한 최신 행을 선택 (0) | 2020.05.25 |
---|---|
[SQL] SQL 서버 조건부 흐름 (0) | 2020.05.25 |
[SQL] 5,15,30 60 분 간격으로 그룹 날짜 시간 (0) | 2020.05.25 |
[SQL] C #으로 SQLite.NET와 마지막 삽입 ID 얻기 (0) | 2020.05.25 |
[SQL] 나는 앱 엔진 애플리케이션과 MySQL 데이터베이스를 사용할 수 (0) | 2020.05.25 |