0

Feistel Cipher을 사용하여 데이터베이스에있는 여러 개의 필드를 업데이트했습니다. 문서에 따르면 암호는 원래 값을 얻기 위해 실행 취소 할 수 있습니다. 필요한 경우 값을 취소 할 수 있습니까?PostgreSQL의 Feistel Cipher를 해독하십시오.

CREATE OR REPLACE FUNCTION pseudo_encrypt(VALUE int) returns bigint AS $$ 
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; 
    l1 := l2; 
    r1 := r2; 
    i := i + 1; 
END LOOP; 
RETURN ((l1::bigint << 16) + r1); 
END; 
$$ LANGUAGE plpgsql strict immutable; 

답변

3

당신은 처음에이 자기 가역 변형을 사용할 수 있습니다 : 여기

원래 암호 기능입니다 대신 bigint을 복용하여 원래 버전과 다릅니다

CREATE FUNCTION rev_pseudo_encrypt(VALUE bigint) returns bigint AS $$ 
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; 
    l1 := l2; 
    r1 := r2; 
    i := i + 1; 
END LOOP; 
RETURN ((r1::bigint<<16) + l1); 
END; 
$$ LANGUAGE plpgsql strict immutable; 

(입력은 여전히 ​​2^32보다 작아야 함), 그리고 두 개의 16 비트 블록이 32 비트 최종 결과로 스와핑된다는 사실에 의해 결정됩니다.

결과의 고유함 외에도 rev_pseudo_encrypt(rev_pseudo_encrypt(x)) = x 속성이 있습니다.
또한 입력 유형이 출력 유형과 동일하다는 장점이 있습니다. 한편

그들의 16 개 비트 블록 알고리즘에 공급되기 전에 교환 될 필요는 원본 의해 생성 된 값을 반전하고, 그 결과는 다시 스왑 :

create function swap16(bigint) returns bigint as 
'select (($1&65535)<<16)+(($1)>>16)' 
language sql stable; 

select pseudo_encrypt(1234); 
pseudo_encrypt 
---------------- 
     223549288 

select swap16(pseudo_encrypt(swap16(223549288)::int)); 
swap16 
-------- 
    1234