OCR を使用して、約 16 ~ 20 文字 (A ~ Z、0 ~ 9) のシリアル番号を読み取りたいと考えています。毎回すべての文字が正しく認識されるとは限らないので、シリアル番号にチェック文字を1つ追加したい。現時点では、シンプルな Luhn mod N algo ( Wikipedia)を見つけました。このアルゴリズムは、転置エラー (09 => 90) に対して安全ではありません。
ウィキペディアからの実装:
char GenerateCheckCharacter(string input) {
int factor = 2;
int sum = 0;
int n = NumberOfValidInputCharacters();
// Starting from the right and working leftwards is easier since
// the initial "factor" will always be "2"
**//int index = 0;**
for (int i = input.Length - 1; i >= 0; i--) {
int codePoint = CodePointFromCharacter(input[i]);
int addend = factor * codePoint;
// Alternate the "factor" that each "codePoint" is multiplied by
factor = (factor == 2) ? 1 : 2;
**//factor = index;**
// Sum the digits of the "addend" as expressed in base "n"
addend = (addend / n) + (addend % n);
sum += addend;
**//index++;**
}
// Calculate the number that must be added to the "sum"
// to make it divisible by "n"
int remainder = sum % n;
int checkCodePoint = (n - remainder) % n;
return CharacterFromCodePoint(checkCodePoint);
}
NumberOfValidInputCharacters() は 36 (A ~ Z、0 ~ 9) になります。
しかし、「factor」変数をシリアル番号内の文字の実際のインデックスに変更すると、以前と同じように安全になりますか? (コードの ** ** 行を参照)