web-dev-qa-db-ja.com

別の4桁の数字から一意のランダムな4桁の数字を生成する

2つの列を持つデータベースがあります。最初の列はインデックス、2番目の列はデータファイルへのパスです。 XとYの2種類のデータファイルがあります。これらのデータファイルは次に処理され、そこからグラフが作成されます。したがって、行の例は次のようになります。

ID___| FilePath
0001 | /X/datafile1wfre.dat
0023 | /X/datafile89_jncd.dat
2349 | /Y/datafile983jew_un.dat
3984 | /Y/datafileindj389.dat

次に、このテーブルを使用して、ランダムな行を選択し、ユーザーにデータファイルのグラフを表示します。彼らがグラフを見て時間を費やした後、私は彼らに尋ねるつもりです、あなたはこのデータファイルがXまたはYであると思いますか?

誰かがグラフを見て、この人が後でそのグラフを表示したいとします。次に、行のIDを指定します。注:テーブルには〜4000のエントリがあります。

ここに問題があります。ファイルパスへのパスがテーブルに追加され、テーブルの前半はX(ID 0001-2000)のパスであり、データベースの後半はY(ID 2001-4000)のパスです。 )。誰かが簡単にこれを理解することができ、IDが表示されると、IDが2000を超えているかどうかに基づいて、IDがXまたはYであると予測できます。

これが私の目標です。 4桁の数値Aを取り、別の(異なる)4桁の数値Bを作成できるアルゴリズムが欲しいのですが、BをAに一意にしたいので、A以外の4桁の数値でBを作成することはできません。以下に例を示します。

0239 would create 9834
7783 would create 3892

9834は0239に固有です。使用している4桁の数字に関係なく、9834を取得する唯一の方法は0239からです。3892と同じで、3892を取得する唯一の方法は7783からです。

このようにして、アルゴリズムから生成された4桁を、テーブルから実際のIDを見ることなくユーザーに提供できます。

4
Tom

あなたがそれを提示したように、この問題に対する根本的に異なる解決策があります。

Aの独立したソースがある場合は、A(プライベートID)からB(パブリックID)への真にランダムなマッピングを作成できます。別の行を作成して番号Aが割り当てられるたびに、ランダムに読み取って番号Bを作成します。Bが一意であることを確認するには、割り当てる前にすべての既存のBを検索する必要があります。これは誰にとってもリバースエンジニアリングが最も困難です。基本的には、暗号化がワンタイムパッドと呼んでいるものです。また、許可したスペースに完全に人口が近づくにつれて、ますます禁止されます。最終的に、Bとして割り当てる番号が1つだけ残っている場所に到達します。ランダムに番号が見つかるまで待つ必要があり、すべての試行で一意性を証明するために検索する必要があります。

関数による数値AのBへの固定変換。これにより、スペースが満杯になっても禁止されなくなります。また、ユーザーがアルゴリズムを推測するリスクもあります。ハッシュを使用してこれを行う代わりに、数値Aを暗号化すると、これを緩和できます。プレーンテキストと同じサイズの暗号テキストを生成し、暗号変数(キー)を取る暗号化アルゴリズムがあります。このようにして、暗号変数(キー)がまだ秘密である限り、Bの作成方法を彼らが推測したとしても、問題にはなりません。 フォーマットを保持する暗号化 を使用する必要があります。これにより、BからAを予測することができますが、データベースでBにインデックスを付ける場合、これは必要ありません。

それがやり過ぎだと思われる場合は、Aを単に難読化するシャッフルを調べることができます。これは、クリプト変数も使用しない限り、シャッフルを推測するリスクがあります。

Aがまだ必要かどうかも検討する価値があります。 Aが提供する唯一のものが一意の識別子である場合、Bが必要なすべての場合、Aに変換して戻すことができず、データベースにAを格納する理由がありません。これは、あなたがしなければならないすべてが一意に 自動インクリメントIDをランダム化する であるということを意味します。一部のDBはすでにこれを提供しています。このようにして、xまたはyを予測せず、不要なレベルの間接参照を回避する一意のIDを取得します。

2
candied_orange

それを考慮:

  • IDの数は有限で小さく(一方のテーブルでは約2k行、もう一方のテーブルでは約2k)
  • 「生成されたエイリアスID」は4つの数字で構成する必要があります。つまり、ハッシュ関数を試した場合、衝突の数が多すぎます。

それから私はお勧めします:

  • 同じテーブルの別の列にエイリアスIDをプリロードするので、リアルタイムで計算する必要はありません。

私はbashを使用してこのソリューションを作成しましたペアを作成します。別の言語で複製できます:

  1. 0000から4000の文字列を含むファイルを作成しました

    $ seq -f "%04g" 0 4000 > /tmp/data.txt

  2. 0000から9999の文字列で2つ目のファイルを作成しました(これは偽のIDになります)

    $ seq -f "%04g" 0 9999 > /tmp/data2.txt

  3. 2番目のファイルをスクランブルしました。

    $ sort -U /tmp/data2.txt > /tmp/data3.txt

  4. 結果のファイルを最初の4001行だけに切り詰めました

    $ head -n 4001 > /tmp/data4.txt

  5. 次に、すべての元のIDをエイリアスIDとペアにしました

    $ paste data.txt data4.txt > data5.txt

その後、シーケンシャルIDとランダムな4番号IDの両方をテーブルに入力するために使用できるファイル(data5.txt)があります。

0000    3675
0001    2464
0002    1808
0003    9569
0004    3309
...
3996    9843
3997    7497
3998    7892
3999    3062
4000    5687

1