1

VAT 番号は、ランダムまたは順番に生成されるのではなく、番号が有効かどうかを確認できる式に基づいています。VAT 番号が無効な場合、企業は VAT を再請求できません。

英国の VAT 番号を手動で検証するには、次の演習を実行できます。

最初の 2 文字を除いて、数字を縦に並べ、それぞれに 8 から始まり 2 で終わる値を掛けます。次に、すべての合計を合計し、答えがマイナスになるまで合計から 97 を差し引きます。マイナスの合計は、VAT 番号の下 2 桁に等しくなければなりません。

たとえば、VAT 番号BLABLAが GB 815382334 の場合、計算は次のようになります。

8 x 8 = 64
1 x 7 = 7 
5 x 6 = 30 
3 x 5 = 15 
8 x 4 = 32 
2 x 3 = 6 
3 x 2 = 6 

上記の計算の合計は64 + 7 + 30 + 15 + 32 + 6 + 6 = 160 、結果がマイナスになるまでこれから 97 を差し引きます。結果は160 – 97 - 97= -34最後の 2 桁と同じです。したがって、VAT 番号は有効です。

英国の VAT 番号を入力として受け取り、上記の式を使用してチェックサムを計算し、番号が有効か無効かを示す C# アプリケーションを作成したいと考えています。

これは私にとってアルゴリズムの演習です。バットチェッカーをオンラインで見つけましたが、それらがどのように機能しているのか理解できません。そのため、誰かが上記の問題に対して適切な説明で簡単な回答を提供できることを望んでいましたか?

更新

    public static bool isValidVATNumber(string theVATNumber)
    {
        string startChar = "^";
        string endChar = "$";
        bool rtn = false;
        int i = 8;
        string valString;
        int sum = 0;
        // Check that the string matches the requirements
        rtn = Regex.IsMatch(theVATNumber, (startChar + ("(([1-9]d{8})|([1-9]d{11}))" + endChar)), RegexOptions.Multiline);
        if (rtn)
        {
            // Perform the validation
            valString = theVATNumber;
            if (Regex.IsMatch(valString, (startChar + "[A-Z]{2}"), RegexOptions.Multiline))
            {
                valString = valString.Substring(2);
            }
            while ((i >= 2))
            {
                sum = (sum
                            + (i * int.Parse(valString.Substring(0, 1))));
                valString = valString.Substring(1);
                i--;
            }
            while ((sum > 0))
            {
                sum -= 97;
            }
            rtn = ((sum * -1)
                        == int.Parse(valString));
        }
        return rtn;
    }

上記の方法は機能せず、理解するのがより難しいことに注意してください。私は自分の方法で作業を開始しましたが、まだ完了していません(恥ずかしいことに注意してください)

    List<int> integerList = new List<int>();
    int b = 8;

    for (int a = 0; a < textBox1.Text.Length; a++)
    {
        integerList.Add(int.Parse(textBox1.Text[a].ToString())); 
    }
    foreach (int item in integerList) 
    {
        listBox1.Items.Add(item * b);
        --b; 
    }

私はまだリストの合計を取り、残りの計算を行う必要があり、他の方法(より簡単な方法)について何人かの人々の頭脳を選ぶことを望んでいました.

以下のPaxのおかげで、私自身の方法とabitを更新します。

    List<int> integerList = new List<int>();
    List<int> sumList = new List<int>();
    int b = 8; // Will be 8 for the first multiplication.

    for (int a = 0; a <= 6; a++)
    {
        integerList.Add(int.Parse(textBox1.Text[a].ToString())); 
    }
    foreach (int item in integerList) // Loop once per input digit.
    {

        //listBox1.Items.Add(item * b);
        sumList.Add(item * b);
        --b; 
    }
    listBox1.DataSource = sumList;

    int sum = sumList.Sum();

    while (sum > 0)
    {
        sum = sum - 97;
    }
    int myInt = System.Math.Abs(sum);
    label1.Text = Convert.ToString(myInt);
4

2 に答える 2

5

さて、これを少しずつ見ていきましょう。コードを持っているとし815382334ましょう。先頭の無関係な文字は既に削除されています。

最初のステップは、文字をループして、数値にインデックスを掛けた現在の合計を維持することです)、疑似コードで:

sum = 0
for pos = 0 to 6 inclusive:
    sum = sum + num_at(pos) * (8 - pos)

上記のループの反復ごとに、文字列から正しい数値を抽出し、それを から始まり までのインデックスで乗算し8ます2。次に、それが変数に追加されsumます。メソッドは、文字コード自体ではなくnum_at()、 0 から 9 までの整数を与える必要があることに注意してください。0x300x39

初心者にとっては、ノギンを CPU として使用してプログラムを実行する方が簡単であることがよくあります。

pos  num_at(pos)  8-pos  add  sum
---  -----------  -----  ---  ---
                                0
 0        8          8    64   64
 1        1          7     7   71
 2        5          6    30  101
 3        3          5    15  116
 4        8          4    32  148
 5        2          3     6  154
 6        3          2     6  160

2 番目のステップでは、仕様に従って、マイナスになるまで 97 を引きます。

while sum > 0:
    sum = sum - 97

(ただし、おそらくモジュロ演算子をより効率的に使用できます)。繰り返しますが、頭の中で実行します。

sum
---
160
 63
 34-

次に、最後の 3 番目のステップとして、最後の 2 桁を (完全な 2 桁の数字として) 追加して、確実にゼロになるようにします。

sum = sum + num_at(7) * 10 + num_at(8)
return (sum == 0);

位置 7 と 8 の数字はそれぞれ3とであるため、マイナスに調整された合計に追加したいものです。4num_at(7) * 10 + num_at(8)34

モジュロ バージョンでは、次のようなことが可能です。

sum = 0
for pos = 0 to 6 inclusive:
    sum = sum + num_at(pos) * (8 - pos)
return ((sum % 97) + num_at(7) * 10 + num_at(8) == 97);

これsum % 97は、負の数を与えるループと事実上同じであるが、最終的に 97 を減算しないため、機能します。したがって、最後の 2 桁を足し戻すと、0 ではなく 97 が得られます (有効な VAT 番号の場合)。

例として、はあなたに を与え、160 % 97あなた63に を63 + 34与えます97


ここで、追加したコード フラグメントに基づいて、おそらく 9 桁のものと 12 桁のものの両方のタイプの VAT 番号を処理する必要があります。投稿されたコード フラグメントは、長さチェック、単純な文字列のインデックス作成、および文字チェックで十分な正規表現チェックと部分文字列化をすべて行う必要があるため、おそらく必要以上に複雑です。

于 2013-08-21T01:50:20.703 に答える