1

バーコードのチェック ディジットの計算方法に関する私の理解に基づいて、次のようになります。

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 は、方程式/式の最後の部分についての私の理解を修正します。「10 の最も近い等しいかそれ以上の倍数から合計を引く = 60- 57 = 3(チェックデジット)」

したがって、04900000634 の場合、合計は 40 になります。その式に基づいて、40 の「10 の最も近い等しいかそれ以上の倍数」は 40 であるため、40-40=0 であり、それがチェックになると予想されます。合計(6ではない)...だから、まだ混乱している...

更新 3

理由はまだわかりませんが、sumOddVals() 関数と sumEvenVals() 関数で "==" と "!=" のロジックを逆にすると、私の結果はhttpによって生成された結果に対応するため、mike z のコメントは正しいに違いありません。 ://www.gs1us.org/resources/tools/check-digit-calculator

更新 4

どうやら、 http://en.wikipedia.org/wiki/European_Article_Numberに基づいて、チェック ディジットの計算の背後にある権力は、最初の位置を位置 0 ではなく、位置 1 と見なします。 1 ではなく、インデックス 0 に存在する最初のアイテム!

4

3 に答える 3

2

チェック ディジットは常に最後です。

チェック ディジットのすぐ左にある数字から始めて左に移動し、各数字を合計し、3 と 1 の重みを交互に適用します。

チェック ディジットは、10 の倍数の結果を生成するために追加する必要がある数値です。

これは、すべての EAN/UPC コードで機能します - UPC-E、EAN-8 (0、6、または 7 で始まるものを除くすべての有効な 8 桁のコード) UPC-A (12 桁)、EAN-13、EAN- 14 (「TUN」または「カートン」コードと呼ばれることもあります) および SSCC (実際には 18 桁ですが、AI が「00」の EAN128 標準の一部として実装されているため、20 桁のコードであると誤解する人もいます)

UPC-E が導入されたとき、元のスキームは [言語][会社][製品][小切手] でした。0、6、および 7 は英語に割り当てられ、残りは割り当てられませんでした。[company] と [product] は合計 6 桁の可変長です。製品数の多い企業には短い企業番号を、製品数の少ない企業には長い企業番号を使用します。

EAN は残りの番号を使用しましたが、国が 2 桁である [国][会社][製品][小切手] を割り当てました。

このシステムはすぐになくなりましたが、非常に小さな製品や、UPC-A/EAN-13 が導入される前に番号が付けられていた元の製品に割り当てられることがあります。

UPC-A は UPC-E と同じスキーマを使用しましたが、「言語」への参照が失われました。0、6、7 は米国/カナダに割り当てられました。会社+製品は10桁に拡張されました。

EAN-13 はスキームを 13 桁に拡張しました。国は 2 桁、会社と製品は 10 桁、チェックは 1 桁です。UPC-A は、先頭に「0」を付けることで互換性がありました。

13 桁のスキームを実装することで、米国企業はこれらの各コードを追跡できるようになり、すでに EAN-13 が割り当てられている製品に UPC-A を発行する必要がなくなりました。約8年前に完成予定だったが、まだ遅れている企業もある。

EAN-14 はカートンの外装に使用されます。先頭の数字は通常、「取引単位識別子/番号」と呼ばれます。したがって、コード全体が TUN と呼ばれることもあります。最初は、先頭の数字 (1=1doz、2=2doz など) を体系化する試みがありましたが、これはすぐに放棄されました。ほとんどの企業は、パッケージ レベルとして数字を使用します (1 = 個々のアイテムのクラスター、2 = クラスターのトレイ、3 = トレイのボックス - 各企業の好みによって異なります。9 は予約済みです。0 を使用することはお勧めできません (一部の企業では、これは、13 桁のコードと同じチェック ディジットを生成するためです。私はこれを非小売商品のバッチ番号を持つ EAN128 コードに使用しました; AI=01;EAN-14 (=TUN=0 の EAN13) ;AI=10;バッチ番号。

SSCC はワームの別の缶です。それらは 18 桁です。最初の桁はもともと物流記述子として使用されていたもので、次に国コード、製造業者コード、およびパッケージ番号とチェック ディジットがあります。もともと、「3」は「外部」パレット、「4」は「内部」パレットを意味していましたが、これは「内部」パレットが「外部」に送られ、その逆の場合は番号を付け直さなければならないため、実用的ではなくなりました。 -逆。

そしてもちろん、より多くの国がこのシステムを採用するようになったため、2 桁の国コードは 3 桁に取って代わられました。

于 2013-09-12T16:49:50.487 に答える
1

これに基づいて: http://www.gs1.org/barcodes/support/check_digit_calculator、バーコードの最終的な長さが偶数 (チェックサム値を含む) であるかどうかに基づいて、バーコード計算式は 1 で始まるか、3 で始まるかのいずれか) または追加します。チェックサムを含む文字の総数が偶数の場合、1 桁目の重みは 3 です。それ以外の場合 (文字数の合計が奇数)、1 桁目の重みは 1 です。

しかし、それらは常に重み 3 で終わるように見えます。したがって、バーコードの長さや奇数か偶数かは関係ありません。最後の桁の重みが 3 であると仮定して、単純に値を「逆方向」に計算します。ただし、バーコードの長さが偶数か奇数か、つまり、最後の桁とそれに続く桁が偶数か奇数かで世界は大きく変わるので、それにも注意が必要です。「内側」の序数は、バーコードの最後から 2 番目の文字で始まり、後方に 1 つスキップします。「外側の」序数は最後の序数であり、次にすべての序数です。とにかく、これは、私の知る限り、すべてのバーコード タイプのチェック ディジットを生成および検証/検証するために機能するコードです。

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;
}
于 2013-09-04T18:11:45.303 に答える