【发布时间】:2013-09-08 06:06:04
【问题描述】:
根据我对如何计算条形码的校验位的理解,即:
0) Sum the values of all the characters at odd indexes (1, 3, etc.)
1) Multiply that sum by 3
2) Sum the values of all the characters at even indexes (o, 2, etc.)
3) Combine the two sums from steps 1 and 2
4) Calculate the check digit by subtracting the modulus 10 of the combined sum from 10
例如,条形码“04900000634”的总和为 40*;要获得校验和,模数 (40 % 10) == 0,然后是 10 - 0 == 10。
- 奇数字符 == 7; X3 = 21;偶数个字符 == 19,总和为 40。
既然校验位是一个标量值,如果校验位计算的结果是10呢?使用“0”还是“1”?
这是我正在使用的代码(感谢这里的一些帮助:Why does 1 + 0 + 0 + 0 + 3 == 244?);我假设上面的伪代码公式适用于条形码的长度(8 个字符、12 个字符等)和类型(128、EAN8、EAN12 等)。
private void button1_Click(object sender, EventArgs e)
{
string barcodeWithoutCzechSum = textBox1.Text.Trim();
string czechSum = GetBarcodeChecksum(barcodeWithoutCzechSum);
string barcodeWithCzechSum = string.Format("{0}{1}", barcodeWithoutCzechSum, czechSum);
label1.Text = barcodeWithCzechSum;
}
public static string GetBarcodeChecksum(string barcode)
{
int oddTotal = sumOddVals(barcode);
int oddTotalTripled = oddTotal*3;
int evenTotal = sumEvenVals(barcode);
int finalTotal = oddTotalTripled + evenTotal;
int czechSum = 10 - (finalTotal % 10);
return czechSum.ToString();
}
private static int sumEvenVals(string barcode)
{
int cumulativeVal = 0;
for (int i = 0; i < barcode.Length; i++)
{
if (i%2 == 0)
{
cumulativeVal += Convert.ToInt16(barcode[i] - '0');
}
}
return cumulativeVal;
}
private static int sumOddVals(string barcode)
{
int cumulativeVal = 0;
for (int i = 0; i < barcode.Length; i++)
{
if (i % 2 != 0)
{
cumulativeVal += Convert.ToInt16(barcode[i] - '0');
}
}
return cumulativeVal;
}
更新
这里的计算器:http://www.gs1us.org/resources/tools/check-digit-calculator 声称 04900000634 的校验位是 6
这是怎么得出的?
更新 2
这个http://www.gs1.org/barcodes/support/check_digit_calculator 修改了我对方程式/公式最后一部分的理解,其中说:“从最接近的等于或大于十的倍数中减去总和 = 60-57 = 3(校验位)”
因此,在 04900000634 的情况下,总和为 40。根据该公式,40 的“最接近等于或大于 10 的倍数”是 40,因此 40-40=0,我希望是校验和(不是 6)...所以,还是很困惑...
更新 3
我还不明白为什么,但 mike z 的评论一定是正确的,因为当我反转 sumOddVals() 和 sumEvenVals() 中的“==”和“!=”逻辑时函数,我的结果对应http://www.gs1us.org/resources/tools/check-digit-calculator生成的结果
更新 4
显然,基于http://en.wikipedia.org/wiki/European_Article_Number,校验位计算背后的权力不认为第一个位置是位置 0,而是位置 1。对于开发人员来说很困惑,被训练将第一个项目视为驻留在索引 0 ,而不是 1!
【问题讨论】:
-
我已经更新了我的答案。我相信最准确的描述是权重始终对齐,最后一位数字的权重为 3。这将允许该算法适用于所有 EAN 类 - 8、12、13 或 14 位数字。
-
谢谢;我自己也得出了这个结论。
标签: c# barcode barcode-printing