C# 我需要什么代码来计算任何条形码的校验和,以及验证/验证现有校验和?
有许多条形码类型和大小(长度)。是否有一套通用算法可用于计算任何条形码的校验和?条形码虽然长度不同,语义不同,但在生成校验和时仍遵循一些基本规则。下面的代码可以复制到一个小的util中进行测试(或者简单地使用非事件处理代码): 要使用此功能,请创建WinForms应用程序,并在其上删除以下控件:C# 我需要什么代码来计算任何条形码的校验和,以及验证/验证现有校验和?,c#,barcode,barcode-scanner,checksum,C#,Barcode,Barcode Scanner,Checksum,有许多条形码类型和大小(长度)。是否有一套通用算法可用于计算任何条形码的校验和?条形码虽然长度不同,语义不同,但在生成校验和时仍遵循一些基本规则。下面的代码可以复制到一个小的util中进行测试(或者简单地使用非事件处理代码): 要使用此功能,请创建WinForms应用程序,并在其上删除以下控件: 0) A button named button1; give it text something like "Calculate barcode and append it to label belo
0) A button named button1; give it text something like "Calculate barcode and append it to label below", if desired
1) A button named button2; give it text something like "Valid barcode + czech digit", if desired
2) A label named label1, which displays the result of clicking button1
3) A textBox named textBox1, wherein you enter a raw barcode value (sans check digit) prior to clicking button1 OR enter a full barcode value (with check digit) prior to clicking button2
// "Calculate check sum" handler
private void button1_Click(object sender, EventArgs e)
{
string barcodeWithoutCheckSum = textBox1.Text.Trim();
string checkSum = GetBarcodeChecksum(barcodeWithoutCheckSum);
string barcodeWithCheckSum = string.Format("{0}{1}", barcodeWithoutCheckSum, checkSum);
label1.Text = barcodeWithCheckSum;
textBox1.Focus();
}
// Verify/validate existing checksum handler
private void button2_Click(object sender, EventArgs e)
{
string bcVal = textBox1.Text.Trim();
bool validCheckDigit = isValidBarcodeWithCheckDigit(bcVal);
MessageBox.Show(validCheckDigit ? string.Format("{0} is valid", bcVal) : string.Format("{0} invalid", bcVal));
}
public static string GetBarcodeChecksum(string barcode)
{
int oddTotal;
int oddTotalTripled;
int evenTotal;
// Which positions are odd or even depend on the length of the barcode,
// or more specifically, whether its length is odd or even, so:
if (isStringOfEvenLen(barcode))
{
oddTotal = sumInsideOrdinals(barcode);
oddTotalTripled = oddTotal * 3;
evenTotal = sumOutsideOrdinals(barcode);
}
else
{
oddTotal = sumOutsideOrdinals(barcode);
oddTotalTripled = oddTotal * 3;
evenTotal = sumInsideOrdinals(barcode);
}
int finalTotal = oddTotalTripled + evenTotal;
int modVal = finalTotal%10;
int checkSum = 10 - modVal;
if (checkSum == 10)
{
return "0";
}
return checkSum.ToString();
}
private static bool isStringOfEvenLen(string barcode)
{
return (barcode.Length % 2 == 0);
}
// "EvenOrdinals" instead of "EvenVals" because values at index 0,2,4,etc. are seen by the
// checkdigitmeisters as First, Third, Fifth, ... (etc.), not Zeroeth, Second, Fourth
private static int sumInsideOrdinals(string barcode)
{
int cumulativeVal = 0;
for (int i = barcode.Length-1; i > -1; i--)
{
if (i % 2 != 0)
{
cumulativeVal += Convert.ToInt16(barcode[i] - '0');
}
}
return cumulativeVal;
}
// "OddOrdinals" instead of "OddVals" because values at index 1,3,5,etc. are seen by the
// checkdigitmeisters as Second, Fourth, Sixth, ..., not First, Third, Fifth, ...
private static int sumOutsideOrdinals(string barcode)
{
int cumulativeVal = 0;
for (int i = barcode.Length - 1; i > -1; i--)
{
if (i % 2 == 0)
{
cumulativeVal += Convert.ToInt16(barcode[i] - '0');
}
}
return cumulativeVal;
}
private static bool isValidBarcodeWithCheckDigit(string barcodeWithCheckDigit)
{
string barcodeSansCheckDigit = barcodeWithCheckDigit.Substring(0, barcodeWithCheckDigit.Length - 1);
string checkDigit = barcodeWithCheckDigit.Substring(barcodeWithCheckDigit.Length - 1, 1);
//MessageBox.Show(string.Format("raw barcode portion is {0}", barcodeSansCheckDigit));
//MessageBox.Show(string.Format("check portion is {0}", checkDigit));
return GetBarcodeChecksum(barcodeSansCheckDigit) == checkDigit;
}
是的,有一种非常常见的校验和计算器算法。各种条形码(和其他数字输入方案)使用它们来验证扫描仪(或人员)是否正确输入了所有数字。最早的例子之一,也是最普遍理解的校验和算法是Luhn算法,它以在信用卡上使用而闻名;但它有许多不同之处。然而,在他们的核心,大多数使用相同的算法 通用算法使用与数字位置相对应的权重数组、模除数和指示“产品添加”或“产品数字添加”方案的标志 伪码 共同计划 校验数字方案在各个行业中普遍使用,条形码生产和验证只是其中之一。以下是可用于此算法的一些常见校验位方案的列表:
- UPC-A条码:权重为{3,1,3,1,3,1,1,3,1,1,3,1}的12位数字,除数为10,productDigitAdd值为假
- EAN-13条码:权重为{1,3,1,3,1,3,1,3,1,1,3,3,1},除数为10,productDigitAdd值为假
- 代码128条形码:数字是条形码的代码值,而不是条形码包含的值(例如,在模式A和B中,条形码符号值65表示ASCII字母“A”,但在模式C中是一对数字“33”);权重是{1,2,3,4,5…通过条形码符号总数1},其中1是右端的校验位权重;除数是103;并且productDigitAdd值为false
- POSTNET条形码:权重为{1,1,1,1,1,1,1,1,1},除数为10,productDigitAdd值为false
- 16位信用卡:权重是由16位数字组成的数组,{2,1,2,1…2,1},除数是10,productDigitAdd值为真。这是卢恩算法
- ISBN(书号):权重为{10,9,8,7,6,5,4,3,2,1},除数为11,productDigitAdd字段为false
- 路由中转号(在银行支票上):权重为{3,7,1,3,7,1,3,7,1},除数为10,ProductDigitAddd字段为false
<-31
1313131313131
9780321146533
在第二篇文章中,可以在这里找到三种不同的计算条形码的方法(一种是ab
<-31
1313131313131
9780321146533