增值税号码不是随机或顺序生成的,而是基于可以检查以查看该号码是否有效的公式.如果增值税号无效,则企业无法重新申请增值税.
要手动验证英国增值税号,您可以执行以下练习:
排除前两个字母,垂直列出数字,并将每个数字乘以一个以8开头并以2结尾的值.然后将所有总和相加,并从总和中扣除97,直到答案为负数.负数应等于增值税号的最后2位数.
因此,例如,增值税号为BLABLAGB 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
Run Code Online (Sandbox Code Playgroud)
上述计算的总和是64 + 7 + 30 + 15 + 32 + 6 + 6 = 160
从此扣除97,直到结果为负,结果160 – 97 - 97= -34与最后两位数相同:因此增值税号有效.
我想编写一个C#应用程序,它将英国增值税号作为输入,使用上面的公式计算校验和,并指出该数字是有效还是无效.
这对我来说是算法练习.我在网上找到了vat checkers,但是我不明白它们是如何工作的,所以我希望有人可以通过很好的解释给出上述问题的一些简单答案?
更新:
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;
}
Run Code Online (Sandbox Code Playgroud)
注意上面的方法不起作用,对我来说更难理解,我开始用我自己的方法,我发现更容易使用但尚未完成它(请注意它是令人尴尬的)
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;
}
Run Code Online (Sandbox Code Playgroud)
我仍然需要得到列表的总和并进行其余的计算,并希望选择一些人的大脑,以了解其他方式(更简单的方法).
更新我自己的方法,并在下面感谢Pax:
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);
Run Code Online (Sandbox Code Playgroud)
好的,让我们一点一点地看一下.假设你有代码815382334- 你已经删除了前面的无关字符.
第一步是在伪代码中循环遍历字符并保持数值乘以索引的运行总数:
sum = 0
for pos = 0 to 6 inclusive:
sum = sum + num_at(pos) * (8 - pos)
Run Code Online (Sandbox Code Playgroud)
对于上面循环的每次迭代,您从字符串中提取正确的数字,并将其乘以其索引,该索引从8和从下开始2.然后将其添加到sum变量中.请记住,该num_at()方法需要为您提供从0到9的整数,而不是字符代码本身,这可能是0x30通过0x39.
我经常发现初学者更容易坐下来使用他们的noggin作为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
Run Code Online (Sandbox Code Playgroud)
第二步,按照规范减去97直到你变为负数:
while sum > 0:
sum = sum - 97
Run Code Online (Sandbox Code Playgroud)
(尽管你可以更有效地使用模运算符).而且,再一次,在脑海里运行它:
sum
---
160
63
34-
Run Code Online (Sandbox Code Playgroud)
然后,作为第三步也是最后一步,添加最后两位数字(作为一个完整的两位数字),以确保您得到零:
sum = sum + num_at(7) * 10 + num_at(8)
return (sum == 0);
Run Code Online (Sandbox Code Playgroud)
由于在位置7和8的号码3,并4分别num_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);
Run Code Online (Sandbox Code Playgroud)
这sum % 97是有效的,因为它实际上与循环给你一个负数但没有最后减去97.因此,当你加回最后两位数时,你将获得97而不是0(对于有效的增值税号).
举个例子,160 % 97给你63并63 + 34给你97.
现在,根据您添加的代码片段,您可能需要处理两种类型的增值税号码,9位数字和12位数字.发布的代码片段可能比所有正则表达式检查和子字符串更复杂,其中长度检查,简单的字符串索引和字符检查就足够了.
| 归档时间: |
|
| 查看次数: |
4145 次 |
| 最近记录: |