4

追跡番号( tracking_number、natchと呼ばれる)を検出するためのgemを書いています。テキストで有効な追跡番号の形式を検索し、それぞれのサービスの仕様で指定されているチェックサム計算を通じてそれらの形式を実行して、有効な番号を決定します。

先日、USPS Certified Mailを使用して手紙を郵送し、USPSから付随する追跡番号を取得し、それを私の宝石に送りましたが、検証に失敗しました。私は計算を正しく実行しているとかなり確信していますが、アイデアが不足しています。

この番号は、次のドキュメントのセクション2.8(15ページ)で説明されているように、USSコード128を使用して検証されます。http ://www.usps.com/cpim/ftp/pubs/pub109.pdf

郵便局から受け取った追跡番号は「7196901075600307 7385」で、チェックディジットの計算に使用しているコードは次のとおりです。

def valid_checksum?
  # tracking number doesn't have spaces at this point
  chars = self.tracking_number.chars.to_a
  check_digit = chars.pop

  total = 0
  chars.reverse.each_with_index do |c, i|
    x = c.to_i
    x *= 3 if i.even?
    total += x
  end

  check = total % 10
  check = 10 - check unless (check.zero?)
  return true if check == check_digit.to_i
end

提供された仕様に基づく私の計算によると、有効であるためには最後の桁が3である必要があります。ただし、Googleの追跡番号の自動検出では、番号がそのまま検出されるため、何か間違ったことをしているとしか思えません。

4

2 に答える 2

10

私の手動計算から、それはあなたのコードがすることと一致するはずです:

posn: 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2   sum  mult
even:  7     9     9     1     7     6     0     0     7     8    54   162
 odd:     1     6     0     0     5     0     3     7     3       25    25
                                                                       ===
                                                                       187

したがって、チェックディジットは3でなければなりません。

その数が有効である場合、彼らはあなたが思っているものとは異なるアルゴリズムを使用しています。

あなたが与えた番号をUSPSトラッカーページに差し込むと、そのパス全体が見えるので、そうかもしれないと思います。


実際、出版物9191 、確認サービステクニカルガイドを見ると、追跡アプリケーションIDの先頭を含め、2桁の余分な数字が使用されていることがわかります。その出版物にあるアルゴリズムを適用すると、次のようになります。

posn: 22 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2   sum  mult
even:  9     7     9     9     1     7     6     0     0     7     8    63   189
 odd:     1     1     6     0     0     5     0     3     7     3       26    26
                                                                             ===
                                                                             215

そしてそれは確かにあなたに5のチェックディジットを与えるでしょう。私はそれが答えだと言っているわけではありませんが、それは事実と一致し、少なくとも実行可能な説明です。

おそらくあなたの最善の策は、情報についてUSPSに連絡することでしょう。

于 2011-02-22T04:22:52.097 に答える
2

Rubyはわかりませんが、偶数ごとに3を掛けているように見えます。そして、私が仕様を読む方法では、すべての偶数桁を合計し、その合計に3を掛けます。実行された例の20〜21ページを参照してください。

(後で)あなたのコードは正しいかもしれません。このPythonスニペットは、例として7、あなたの例として3を示しています。


#!/usr/bin/python
'check tracking number checksum'
import sys
def check(number = sys.argv[1:]):
 to_check = ''.join(number).replace('-', '')
 print to_check
 even = sum(map(int, to_check[-2::-2]))
 odd = sum(map(int, to_check[-3::-2]))
 print even * 3 + odd
if __name__ == '__main__':
 check(sys.argv[1:])

[後で追加]参考のために、コードを完成させるだけです。


jcomeau@intrepid:~$ /tmp/track.py 7196 9010 7560 0307 7385
False
jcomeau@intrepid:~$ /tmp/track.py 91 7196 9010 7560 0307 7385
True
jcomeau@intrepid:~$ /tmp/track.py 71123456789123456787
True
jcomeau@intrepid:~$ cat /tmp/track.py 
#!/usr/bin/python
'check tracking number checksum'
import sys
def check(number):
 to_check = ''.join(number).replace('-', '')
 even = sum(map(int, to_check[-2::-2]))
 odd = sum(map(int, to_check[-3::-2]))
 checksum = even * 3 + odd
 checkdigit = (10 - (checksum % 10)) % 10
 return checkdigit == int(to_check[-1])
if __name__ == '__main__':
 print check(''.join(sys.argv[1:]).replace('-', ''))
于 2011-02-22T04:13:41.053 に答える