@rossum は次のように述べています。
暗号は 1 対 1 のマッピングであり、それ以外の場合は復号化できません。したがって、任意のブロック暗号は、数値 0、1、2、3、4、5、... を異なる n ビットの数値にマッピングします。ここで、n は暗号のブロック サイズ (ビット単位) です。
そのため、xor 暗号化やビットごとのリバースでさえ、いくつかの目的には十分です。
そして、単純な 1 対 1 暗号化として xor とビットごとの反転を使用する php 関数を次に示します。
これは、すべての値の入力が保証され、同一の値がない疑似乱数ジェネレーターです。n:0..63 を指定すると、ランダムな 0..63 が提供されます。
0..63、0..127 などの 2^i 範囲のみを受け入れます。
暗号学的に安全ではないなど、ランダムです。
このような関数は、ガベージ コレクション ルーチンに非常に適しています。ランダムに実行しても、同じ領域を 2 回クリーニングしようとしないためです。
function math_random_filled($n,$bits,$seed)
{
//bits: examples: 6=0..63, 8=0..255, 10: 0..1023
//n: 0<= n <2^$bits
//seed: any string or number
//generate xor: crc32 + bit mask
$xor= crc32($seed.'internalseed') & ~(-1<<$bits);
//xor
$r=intval($n)^$xor;
//bitwise reverse
$r=bindec(strrev(str_pad(decbin($r),$bits,'0',STR_PAD_LEFT)));
return $r;
}
//demonstration
$bits=6;
$min=0;
$max=pow(2,$bits)-1;
$count=$max-$min+1;
for($n=0;$n<=$max;$n++)
{
$r=math_random_filled($n,$bits,$seed='someseed');
echo " $r ";
$ar[$r]=1;
}
$set=0;
for($n=0;$n<=$max;$n++)
if(isset($ar[$n])) $set++;
echo "\n"."bits: $bits, count: $count, set: ". $set."\n\n";
出力例:
37 5 53 21 45 13 61 29 33 1 49 17 41 9 57 25 39 7 55 23 47 15 63 31 35 3 51 19 43 11 59 27 36 4 52 20 44 12 60 28 32 0 48 16 40 8 56 24 38 6 54 22 46 14 62 30 34 2 50 18 42 10 58 26
bits: 6, count: 64, set: 64
ここでコードをphpサンドボックスでテストできます
これは別のものですが、2 のべき乗だけでなく、任意の範囲を受け入れます。
function math_random_filled_arithmetical($n,$max,$seed)
{
/*
- produces 0..max, repeatable, unique, one-to-one mapped random numbers
- uses arithmetic operations to imitate randomness
- $n: 0<=$n=<$max
- $max: any integer, not only power of two
- $seed: any string or number
*/
$n=intval($n);
$max=intval($max);
$opt1=$n;
$opt2=$max-$n;
$n2=min($opt1,$opt2);
$reverseit=crc32($seed.'internalseed'.$n2)&1;
if($opt1>$opt2) $reverseit=!$reverseit;
$max2=floor(intval($max-1)/2);
//echo "n:$n, max:$max,n2:$n2,max2:$max2,reverseit:$reverseit\n";
if($max>=3)
if($opt1!=$opt2)
$n2=math_random_filled_arithmetical($n2,$max2,$seed.'*');
$res=$reverseit? $max-$n2:$n2;
$res=intval(fmod($res+(crc32($seed)&(1<<30)),$max+1));
//echo "n:$n, max:$max, res:$res\n";
return $res;
}
//demonstration
$max=41;//-- test a max value
for($n=0;$n<=$max;$n++)
{
$r=math_random_filled_arithmetical($n,$max,$seed='someseed');
$ar[$r]=1;
echo " $r ";
}
$filled=0;
for($n=0;$n<=$max;$n++)
if(isset($ar[$n])) $filled++;
echo "\n count: ".($max+1).", filled: ". $filled."\n";
出力例:
20 19 18 17 33 32 37 36 14 13 31 34 35 26 16 11 12 3 39 40 0 41 1 2 38 29 30 25 15 6 7 10 28 27 5 4 9 8 24 23 22 21
count: 42, filled: 42
関連するphpサンドボックスはこちら