0

この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;
4

1 に答える 1

3

最初に、この自己可逆バリアントを使用できます。

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;

これは元のバージョンとは異なり、bigint代わりにint入力として取ります (ただし、入力は依然として 未満である必要があります2^32)。また、2 つの 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
于 2013-08-28T14:30:06.110 に答える