Code128 バーコードのチェック ディジット計算 (他のほとんどの標準的なバーコード タイプとは根本的に/劇的に異なる) の私の理解*に基づいて、以下の私のコードは正しいです。ただし、トレンチコート (またはラボ) コートに取り付けられたトレンチからの泥/経験的観察/泥をよく知っている可能性がある人による「健全性チェック」をいただければ幸いです。
- これは私の理解です:
バーコードの各文字は、左から順に ASCII コード (IOW、バーコード文字「1」は ASCII コード 49 などと見なされる) に変換され、その値に序数が掛けられます。文字配列内の位置。
たとえば、作成されたバーコード番号「123456789」の場合、「1」は 49、「2」は 50、...「9」は 57 に相当します。
次に、各文字の序数位置にその ASCII 値を掛けます。例: 1*49 == 49、2*50==100、... 9*57==513。次に、これらすべてを合計すると、(この場合) 2,445 になります。
次のステップは、その数を Code128 の「マジック ナンバー」である 103 で割ることです。関心のある値はモジュラスです。したがって、この場合、2445 % 103 == 76 です。
最後から 2 番目に、その値 (76) を ASCII コードと見なして変換し、反対方向をその「プレゼンテーション」値、つまり「L」に戻します。
最後に、その計算された文字を元のバーコードに追加します。本当に、したがって(さらに苦労したり別れたりしたにもかかわらず)、「123456789L」の値になります。
これが正しい値でない場合、私は何かを間違って理解しています。
以下にいくつかのバーコードを示します。
0) 123456789
1) 12345678
2) 1234567
3) 123456
...そして、それらが計算されたチェック ディジットでどのように表示されるか (そして、以下のコードで):
0) 123456789L
1) 12345678N
2) 1234567*
3) 123456E
最後に、Code128 チェック ディジットの計算に使用したコードを次に示します。
private void buttonAppendCode128CheckDigit_Click(object sender, EventArgs e)
{
const int CODE_128_DIVISOR = 103;
string barCode = textBoxRawCode128.Text.Trim();
int runningTotal = 0;
for (int i = barCode.Length - 1; i > -1; i--)
{
char valToConvertToASCII = Convert.ToChar(barCode[i]);
int valToMultiply = ConvertToASCIIInt(valToConvertToASCII);
runningTotal += (valToMultiply*(i + 1));
}
int code128Modulus = runningTotal%CODE_128_DIVISOR;
textBoxCode128WithCheckDigit.Text = barCode + ConvertToASCIIChar(code128Modulus);
}
private char ConvertToASCIIChar(int code128Modulus)
{
return (char) code128Modulus;
}
private int ConvertToASCIIInt(char valToConvertToASCII)
{
return valToConvertToASCII;
}
アップデート
私はブライアン・アンダーソンの答えを完全に理解しているわけではありません。彼は正しいかもしれません (おそらくそうです) が、チェック ディジットの計算が行われる限り、スタート ビットとストップ ビットは無視されると思います。それらは、バーコード スキャナがどのポイントから注意を払い、その後どのポイントから電子スヌーズを再開できるかを知るためだけにあるのではないでしょうか?
そして、数学 (ブライアンが ASCII 値から 32 を引く必要があることについて正しい場合) は次のようになります。
(17*1)+(18*2)+(19*3)+(20*4)+(21*5)+(22*6)+(23*7)+(24*8)+(25*9)
-or:
17 + 36 + 57 + 80 + 105 + 132 + 161 + 192 + 225 == 1005
開始文字は計算に含まれるのに、停止文字は含まれないのはなぜですか?
1005 % 103 == 78 なので、チェック ディジットは ... "N" ... または (78-32 == 46) "-" になりますか?
ストップ文字とスタート文字の両方が含まれていれば、もちろん解決策も変わります...
更新 2
私は正確にはバーコードのオグラではないので、そのようなものを見たことがあるかもしれませんが、気づいていない/注意を払っていないかもしれませんが、バーコードに "-" や " " などのチェック ディジットを含めることはできますか? 奇妙に思えます。数字だけでなく、常に英数字であることを期待しています。私の疑いが正しければ、計算が "-" または " " または "~" などの奇妙なチェック ディジットになった場合、どうすればよいでしょうか?
更新 3
したがって、Brian やその他の情報源を正しく理解できれば、バーコード スキャナーから、意味的にデコードされたものを読み取ります。
[startChar]123456789[checkDigit][stopChar]
...しかし、これは論理的に停止文字を削除します-それはチェックデジットの計算の一部ではないため-そして(論理的にはそれほど論理的ではありませんが)チェックデジットも削除するため、実際に得られるのは次のようになります:
[startChar]123456789
...そしてそれをマッサージし、チェックデジットを計算して、バーコードの人間が読める表現を表示します:
123456789[checkDigit]
そして、バーコードがスキャンされた場合、開始文字が明らかに (?) 見られるので、計算される runningTotal 値に事前に追加するだけです。したがって、私のコードは次のとおりです。
private void buttonAppendCode128CheckDigit_Click(object sender, EventArgs e)
{
const int CODE_128_DIVISOR = 103;
string barCode = textBoxRawCode128.Text.Trim();
int runningTotal = ConvertToASCIIInt(barcode[0]); // Start with the value of the start char; this should always be either 103 (Code128A), 104 (Code128B), or 105 (Code128C); 106 is the stop char
for (int i = barCode.Length - 1; i > 0; i--) // now disregarding already calculated first element by ignoring element 0
{
char valToConvertToASCII = Convert.ToChar(barCode[i]);
int valToMultiply = ConvertToASCIIInt(valToConvertToASCII);
runningTotal += (valToMultiply*(i + 1));
}
int code128Modulus = runningTotal%CODE_128_DIVISOR;
textBoxCode128WithCheckDigit.Text = barCode + ConvertToASCIIChar(code128Modulus);
}
private char ConvertToASCIIChar(int code128Modulus)
{
return (char) code128Modulus;
}
private int ConvertToASCIIInt(char valToConvertToASCII)
{
const int ASCII_ADJUSTMENT_VAL = 32;
return valToConvertToASCII-ASCII_ADJUSTMENT_VAL;
}