3

アプリケーションの偽のカナダの SIN 番号を生成するには、C# で単体テストを作成する必要があります。インターネットを検索した後、ここに私が見つけたものがあります。どうやって始めたらいいのかもわかりません。上の各数値を下の数値で特別に乗算すると、単純な乗算ではないため、混乱します。事前に助けに感謝します。ありがとう。

これは、Google検索から取得したアルゴリズムです。

Algorithm _

Social Insurance Numbers are validated via a simple checksum process.

Let's use this fictitious SIN to demonstrate:

    046 454 286  <  Try substituting your SIN

    046 454 286  \  Multiply each top number
    121 212 121  /  by the number below it..
    -----------
    086 858 276  <  and get this.
             ^
             Notice here that 8*2=16, add 1 and
             6 together and get 7. If you get a
             2 digit # add the digits together.

Add all of these digits together.

0+8+6+8+5+8+2+7+6=50
                  /\
                If the SIN is valid this # will
                be evenly divisible by 10. This
                is a 'valid' SIN.
4

5 に答える 5

8

これは実際には回答に属していませんが、重要であり、コメントに十分なスペースがないため、ここに...


これは、実際のコードの目的はユーザーが入力した SIN を検証することであり、検証コードをテストするためにテスト スイートで SIN をランダムに生成したいと考えているように思えます。それは間違っている。

単体テストでは、ランダム データを生成しないでください。これは、データをまったく使用できないという意味ではありません。10,000 個の良い SIN と 10,000 個の悪い SIN のセットを 1生成し、そのデータを保存してから、それらすべてに対して正しい結果が得られる検証メソッドに対するテストを作成しても問題ありません。重要なルールは次のとおりです。

テストが成功するか失敗するかは、ランダマイザーが特定の実行でたまたま生成したデータに依存するべきではありません。

主なことは、失敗したテストは、失敗の原因となったコードを修正するまで、繰り返し可能な方法で失敗し続けなければならないということです。テスト データがランダムな場合、これは保証できません。

後で、バリデーターが特定の SIN で失敗するというバグが見つかる可能性があります。この時点での正しい応答は、その SIN をテスト データに永続的に追加することです。次に、コードを修正します。このようにして、回帰からも保護されます。

初期のテスト データを生成するためだけにこれを使用することもできますが、それは問題ありませんが、既にデータ セットを提供している Web サイトを見つける方がはるかに簡単だと思います。これは簡単な Google の結果です:
http://www.testingmentor.com/tools/tool_pages/ssnsin.htm

そして、冗談として、私の検証方法は次のようになります (未テスト、返信ウィンドウに直接入力):

bool IsValidSIN(string SIN)
{ 
   //normalize
   SIN = SIN.Trim();
   //account for common input formats that use - . or space as separators
   SIN = SIN.Replace(" ", "").Replace("-","").Replace(".","");

   //basic validations
   if (string.IsNullOrEmpty(SIN)) return false;
   if (SIN.Length != 9) return false;
   if (!SIN.All(c => char.IsDigit(c) ) return false;

   //checksum - we already know here that all characters are digits
   int multiplier = 0;
   int sum = 0;
   foreach (int d in SIN.Select(c => (int)c))
   {
      sum += (d * ((multiplier % 2) + 1)).ToString().Select(c => (int)c).Sum();
      multiplier ++;
   }
   return sum % 10 == 0;
}
于 2013-07-30T17:26:32.033 に答える
1

7の代わりに置く理由16は、スペースが不足しているためだと思います。167

これは、何が起こっているかをよりよく示していると思います。

046 454 286  \  Multiply each top number
121 212 121  /  by the number below it..
-----------
000 000 010  <  and get this (tens are on the top)
086 858 266  <  ... ones are on the bottom.

最終的にはすべての数字を合計するので、7vs . が 1 つ16であっても最終結果に違いはありません。

多くの有効な SIN を生成するには、ランダムな 9 桁の数字を生成し、それらの「チェックサム」を計算し、そのチェックサムを 10 で割った余りを見つけ、1、3、5 の位置の 1 つまたは複数の数字を調整します。正しいチェックサムを取得するには、7 または 9 を使用します。

于 2013-07-30T17:04:42.970 に答える
0
var nas = "046 454 286".Where(x => !Char.IsWhiteSpace(x)).ToList();
var check = "121 212 121".Where(x => !Char.IsWhiteSpace(x)).ToList();

var result = "";
for(int i = 0; i < nas.Count(); ++i){
    int tmp = (int)(nas[i]) * (int)(check[i]);
    var val = tmp < 10 ? tmp : tmp - 9;
    result += val;
}

var sum = result.Aggregate(0, (acc, item) => acc + (int)(item));
if(sum % 10 == 0) Console.WriteLine("valid!"); else Console.WriteLine("invalid!");
于 2013-07-30T18:00:07.040 に答える