C# 条形码的2字符校验位是否使用第一个字符或第二个字符?

C# 条形码的2字符校验位是否使用第一个字符或第二个字符?,c#,barcode,barcode-printing,C#,Barcode,Barcode Printing,根据我对条形码校验位数计算方法的理解,即: 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

根据我对条形码校验位数计算方法的理解,即:

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”

下面是我正在使用的代码(感谢这里的帮助:);我假设不管条形码的长度(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;
}
private void按钮1\u单击(对象发送者,事件参数e)
{
string barcode without Czechsum=textBox1.Text.Trim();
字符串czechSum=GetBarcodeChecksum(没有czechSum的条形码);
string barcodeWithCzechSum=string.Format(“{0}{1}”,barcodeWithCzechSum,czechSum);
label1.Text=带有Czechsum的条形码;
}
公共静态字符串GetBarcodeChecksum(字符串条形码)
{
int oddTotal=总和(条形码);
int oddTotalTripled=oddTotal*3;
int evenTotal=总和(条形码);
int finalTotal=oddTotalTripled+EventTotal;
int czechSum=10-(最终总额为10%);
返回czechSum.ToString();
}
专用静态int-sumEvenVals(字符串条形码)
{
int累积值=0;
对于(int i=0;i
更新 此处的计算器:声明04900000634的校验位为6

这是怎么做到的

更新2 这个 修正了我对等式/公式最后一部分的理解,其中写道,“从十=60-57=3(检查数字)的最近相等或更高倍数中减去总和”

因此,在04900000634的情况下,总和是40。根据这个公式,40的“最接近的等于或高于10的倍数”是40,所以40-40=0,我希望这是校验和(不是6)…所以,仍然很困惑

更新3 我还不明白为什么,但mike z的评论肯定是正确的,因为当我在sumOddVals()和sumEvenVals()函数中反转“==”和“!=”逻辑时,我的结果与

更新4
显然,基于校验数字计算后的功率不考虑第一位置为位置0,而是考虑位置1。让开发人员感到困惑的是,经过培训,他们认为第一项位于索引0,而不是1

不同的条形码格式有不同的权重。您已经描述了EAN格式的格式-1313加权。而UPC使用3131加权方案。ISBN-10使用了完全不同的方案——权重不同,计算是以11模进行的

我认为您使用的参考是假设数字的索引从1开始,而不是从0开始。其效果是您将奇数和偶数字符混合在一起。因此,总和是
3x19+7=64
,因此校验位是6而不是0。对于EAN和UPC,校验位是必须添加到总和中的值,以获得可被10整除的数字

更新

您对校验位算法的描述仅适用于特定类别的EAN条形码,因为权重是对齐的,因此最后一个数字的权重始终为3(请参阅)。因此,根据精确的EAN方案(8、12、13或14位),奇数或偶数的加权方式不同

因此,需要适当的权重

0490000634
31131313131313


求和为64,校验位为6。

不同的条形码格式有不同的权重。您已经描述了EAN格式的格式-1313加权。而UPC使用3131加权方案。ISBN-10使用了完全不同的方案——权重不同,计算是以11模进行的

我认为您使用的参考是假设数字的索引从1开始,而不是从0开始。其效果是您将奇数和偶数字符混合在一起。因此,总和是
3x19+7=64
,因此校验位是6而不是0。对于EAN和UPC,校验位是必须添加到总和中的值,以获得可被10整除的数字

更新

您对校验位算法的描述仅适用于特定类别的EAN条形码,因为权重是对齐的,因此最后一个数字的权重始终为3(请参阅)。因此,根据精确的EAN方案(8、12、13或14位),奇数或偶数的加权方式不同

因此,需要适当的权重

0490000634
31131313131313

给出64和6的校验位。

基于此:,条形码计算公式可以从1开始,也可以从3开始,这取决于条形码的最终长度是偶数(包括校验和值)还是加法。如果包括校验和在内的字符总数为偶数,则第一个数字的权重为三;否则(总字符数为奇数),第一个数字的权重为1。在这两种情况下,3和1交替出现,如“131313…”或“313131…”

但它们似乎总是以3的重量结束;因此,条形码的长度、奇数或偶数都不重要。简单地“向后”计算值,假设最后一个数字的权重为3;但是,条形码的长度是偶数还是奇数,也就是说,最后一个数字和那些改变的数字
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();
}

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);
    return GetBarcodeChecksum(barcodeSansCheckDigit) == checkDigit;
}