28

ユーザーが電話をかけ、電話のキーパッドで確認番号を入力する必要があるアプリケーションに取り組んでいます。

入力した数字が正しいかどうかを検出できるようにしたいと思います。電話システムは有効な番号のリストにアクセスできませんが、代わりにアルゴリズム (クレジット カード番号など) に対して番号を検証します。

要件の一部を次に示します。

  • 有効なランダムコードを入力するのは難しいに違いない
  • タイプミス(桁の入れ替わり、桁違い)をすると有効なコードを取得するのが難しいに違いありません
  • 合理的な数の可能な組み合わせが必要です (1M としましょう)
  • ユーザーのエラーを避けるために、コードはできるだけ短くする必要があります

これらの要件を考えると、どのようにそのような数を生成しますか?

編集 :

@Haaked: ユーザーが電話で入力するため、コードは数値でなければなりません。

@matt b: 最初のステップでは、コードが Web ページに表示されます。2 番目のステップでは、コードを呼び出して入力します。ユーザーの電話番号がわかりません。

フォローアップ : 数値の有効性をチェックするアルゴリズムをいくつか見つけました(この興味深い Google Code プロジェクトを参照してください: checkDigits )。

4

9 に答える 9

33

いくつかの調査の後、私はISO 7064Mod97,10の公式を使用すると思います。IBAN(国際銀行口座番号)の検証に使用されるため、かなり堅実に見えます。

式は非常に単純です。

  1. 番号を取る:123456
  2. 次の式を適用して、2桁のチェックサムを取得します: mod(98 - mod(number * 100, 97), 97) => 76
  3. コードを取得するための連結番号とチェックサム=>12345676
  4. コードを検証するには、次のことを確認しますmod(code, 97) == 1

テスト :

  • mod(12345676, 97) = 1 =>良い
  • mod(21345676, 97) = 50=>悪い!
  • mod(12345678, 97) = 10=>悪い!

どうやら、このアルゴリズムはほとんどのエラーをキャッチします。

もう1つの興味深いオプションは、Verhoeffアルゴリズムでした。検証桁が1つしかないため、実装がより困難です(上記の単純な式と比較して)。

于 2008-09-05T18:30:26.107 に答える
4

1M の組み合わせの場合、6 桁が必要です。誤って有効なコードがないようにするために、ランダム コードが機能する可能性が 1/1000 の 9 桁をお勧めします。また、整合性チェックを実行するために別の数字 (合計 10) を使用することをお勧めします。分布パターンに関しては、ランダムで十分であり、チェック ディジットにより、1 つのエラーが正しいコードにならないようにすることができます。

編集:どうやら私はあなたの要求を完全に読んでいませんでした. クレジット カード番号を使用して、ハッシュ (MD5 または SHA1 など) を実行できます。次に、適切な場所 (たとえば 9 文字) で切り捨てて、基数 10 に変換します。次に、チェック ディジットを追加すると、目的に応じて多かれ少なかれ機能するはずです。

于 2008-09-05T16:33:10.367 に答える
2

コードをセグメント化する必要があります。その一部は、残りのコードの16ビットCRCである必要があります。

確認番号だけが必要な場合は、シーケンス番号を使用します(単一の生成ポイントがあると仮定します)。そうすれば、重複が発生していないことがわかります。

次に、シーケンスの前に、そのシーケンス番号のCRC-16といくつかの秘密鍵を付けます。秘密鍵は、秘密にしておけば、何でも使用できます。少なくともGUIDを大きくしてください。ただし、プロジェクトGutenbergからのWarandPeaceへのテキストである可能性があります。秘密で一定である必要があります。秘密鍵を持っていると、人々は鍵を偽造できなくなりますが、16ビットのCRを使用すると、簡単に解読できます。

検証するには、番号を2つの部分に分割してから、シーケンス番号と秘密鍵のCRC-16を取得します。

シーケンシャル部分をさらに不明瞭にしたい場合は、CRCを2つの部分に分割します。シーケンスの前に3桁、後ろに2桁を配置します(CRCの長さが一定になるようにゼロパッド)。

この方法では、小さいキーから始めることもできます。最初の10個のキーは6桁になります。

于 2008-09-05T18:34:17.487 に答える
1

数字だけでいいの?1 から 1M の間の乱数を作成し (さらに高い値をお勧めします)、Base32 でエンコードすることができます。次に行う必要があるのは、その値を (秘密のソルト値を使用して) ハッシュし、base32 でハッシュをエンコードすることです。次に、おそらくダッシュで区切って、2 つの文字列を一緒に追加します。

そうすれば、着信コードをアルゴリズムで検証できます。コードの左側を取得し、秘密のソルトを使用してハッシュし、その値をコードの右側と比較するだけです。

于 2008-09-05T16:44:19.717 に答える
0

チェックディジットプロジェクトにリンクしましたが、「エンコード」機能を使用することは良い解決策のようです。それは言う:

「不正な」データ(数値以外など)が渡された場合、encodeは例外をスローする可能性がありますが、verifyはtrueまたはfalseのみを返します。ここでの考え方は、encodeは通常、「信頼できる」内部ソース(たとえば、データベースキー)からデータを取得するため、不正なデータが渡されることは例外として、ごく普通のことです。

したがって、エンコード関数にデータベースキー(たとえば5桁)を渡すことができ、要件を満たす番号を取得できるように思えます。

于 2008-09-05T17:13:13.233 に答える
0

ユーザーがヒットしたキーを検出する方法を既に知っていると仮定すると、これはかなり簡単に実行できるはずです。セキュリティの世界では、「ワンタイム」パスワードという概念があります。これは「使い捨てパスワード」と呼ばれることもあります。通常、これらは (簡単に入力できる) ASCII 値に制限されています。[a-zA-z0-9] と、簡単に入力できる記号の束です。コンマ、ピリオド、セミコロン、括弧など。ただし、あなたの場合は、おそらく範囲を [0-9] に制限し、* と # を含めることをお勧めします。

これらのワンタイム コードがどのように生成されるか (または機能するか) の技術的な詳細をすべて説明することはできません。その背後には中間的な数学がいくつかありますが、最初に自分で確認せずに解体します。アルゴリズムを使用して、ワンタイム パスワードのストリームを生成すると言えば十分です。以前のコードをいくら知っていても、次のコードを推測することは不可能です。あなたの場合、リストの各パスワードをユーザーのランダム コードとして使用するだけです。

自分で実装の詳細を説明するのに失敗するのではなく、9 ページの記事を参照して、自分で読むことができるようにします。

于 2008-09-05T16:50:46.673 に答える
0

コードが有効であることをアルゴリズムを介して迅速に判断する必要があるという暗黙の要件があるようです。これにより、ワンタイム パッド番号のリストを単に配布することはできなくなります。

過去に人々がこれを行った方法はいくつかあります。

  1. 公開鍵と秘密鍵を作成します。秘密鍵を使用して 0 ~ 999,999 の数字をエンコードし、結果を渡します。結果をより長いバージョンにするには、いくつかの乱数を投入する必要があります。また、結果を base 64 から base 10 に変換する必要があります。数値が入力されたら、それを base64 に戻します。秘密鍵を適用し、対象の数字が 1,000,000 未満かどうかを確認します (乱数を破棄します)。
  2. 可逆ハッシュ関数を使用する
  3. 特定の値でシードされた PRN から最初の 100 万の数字を使用します。「チェック」関数はシードを取得し、次の百万の値が適切であることを知ることができます。100万個の整数は大量ではないため、毎回それらを生成してコードを受信したときに1つずつチェックするか、プログラムの起動時にすべてをテーブルに保存してソートし、バイナリ検索(比較の最大数)を使用できますスペースの。

他にもたくさんのオプションがありますが、これらは一般的で実装が簡単です。

-アダム

于 2008-09-05T16:51:19.293 に答える
0
  • 妥当な数の可能な組み合わせが必要です (1M としましょう)
  • ユーザーのエラーを避けるために、コードはできるだけ短くする必要があります

少なくとも 100 万の組み合わせが必要な場合は、少なくとも 6 桁が必要です。それは十分に短いですか?

于 2008-09-05T16:33:28.540 に答える
0

確認コードを作成するとき、発信者の電話番号にアクセスできますか?

もしそうなら、発信者の電話番号を使用し、何らかのハッシュ関数を介して実行します。これにより、ステップ 1 で発信者に提供した確認コードが、ステップ 2 で入力したものと同じであることを保証できます (確認するため)。友人の認証コードを使用していないか、単に非常に幸運な推測をしただけです)。

ハッシュについては、10 桁の数値を取得して 10 桁未満のハッシュ結果を出すことが可能かどうかはわかりません (ある程度の衝突を抱えて生活する必要があると思います)。これにより、ユーザーが本人であることを確認できます。

もちろん、ステップ 1 で使用した電話番号がステップ 2 で使用した電話番号と異なる場合、これは機能しません。

于 2008-09-05T16:42:33.790 に答える