2012-01-10 9 views
1

私はバイトのセット(たとえば10バイトまたは15バイト)を取ることができるバイトのPRNGを構築しようとしています。そのバイトのリストを返します。私は暗号について心配していませんが、それはほぼ一様に分散されなければなりません。可能な2^8の組み合わせをすべて打ち負かす必要があり、しばしば立ち往生することなく数字を繰り返す必要があります。暗号ではなく、8ビットの可逆PRNGを書き込もうとしています

私が読んだアルゴリズムのほとんどは、繰り返しを許さないか、損失を誘発し機能を逆転させるモジュラスまたは非循環シフトを使用することを意味します。また、アルゴリズムがカウントを使用した場合、バイトリストの入力が内部PRNGのカウンタが生成時に何であったかを知らないため、逆方向に作業するのは難しいでしょう。

私が探しているのは、あなたのケーキ・食べすぎの状況ですが、私が欠けていた別の解決策がないことを確認したいと思いました。

検索中、同様の要件を持つthis postが見つかりました。私はC#で書いていましたが、実際には構文は重要ではありません。

自分で書こうとしたすべてのアルゴリズムは暗号化されているため、繰り返しに失敗したり、配布が一様ではありません。私は反転、循環シフト、シードマスキングを使用しました。

+0

あなたの参照先の投稿があなたの質問に答えているようです。 –

+0

そのスレッドの答えは暗号を使用しています。私は何かが欠落していない限り、スタックされずに繰り返し出力することはできません。 – digdig

答えて

1

これは機能しますか?

#include <stdio.h> 

int seed = 1; 

int next() { 
    seed = 1664525*seed + 1013904223; 
    return (seed & 0xff)^(seed>>8 & 0xff)^(seed>>16 & 0xff)^(seed>>24 & 0xff); 
} 

int main() { 
    int i; 
    for(i = 0; i < 1000; i++) { 
     printf("%d\n", next()); 
    } 
} 

それは完全な周期で線形合同法(LCG)に基づいているので、各バイトは、最終的に、すべての種によって生成されます。繰り返しがあるようです。そしてそれは基礎となるLCGの一貫性を継承します。

+0

私が見ている大きな問題は、シフティングがシードの一部だけを使って損失を誘発し、何百万という可能な組み合わせが残っていることです。私が何かが欠けていない限り、シードからバイトへの変換は可逆ではありませんが、私はそれが好きです。 – digdig

0

私のアドバイザーは、私たちのグループのHPCシミュレーション作業をサポートするために、元に戻すことができるようにPRNG(L'Ecuyerのclcg4ベース)を変更しました。これらについてはhereを読むことができます。

基本的には、何が行われたかを「アンドゥ」します。予想通り、乱数生成を元に戻してから別の計算パスに沿って同じ値を再生成する必要があります。このコードherehereを見ることができます。 BSDライセンスのコードです。

関連する問題