Почему этот действительный номер отслеживания USPS не проверяется в соответствии с их спецификацией? - PullRequest
3 голосов
/ 22 февраля 2011

Я пишу драгоценный камень для обнаружения номеров отслеживания (называется tracking_number , natch).Он ищет в тексте допустимые форматы номеров отслеживания, а затем пропускает эти форматы путем вычисления контрольной суммы, как указано в спецификации каждой соответствующей службы, для определения действительных номеров.

На днях я отправил письмо по почте, используя USPS Certified Mail, получилсопровождающий номер отслеживания от USPS, и подал его в мой драгоценный камень, и он не прошел проверку.Я вполне уверен, что правильно выполняю расчеты, но у меня закончились идеи.

Число проверяется с использованием кода 128 USS, как описано в разделе 2.8 (стр. 15) следующего документа: http://www.usps.com/cpim/ftp/pubs/pub109.pdf

Номер отслеживания, который я получил в почтовом отделении, был "7196 9010 7560 0307 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 точно распознает номер, поэтому я могу только предположить, что я делаю что-то не так.

Ответы [ 2 ]

7 голосов
/ 22 февраля 2011

Исходя из моих ручных вычислений, оно должно совпадать с тем, что делает ваш код:

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

Следовательно, контрольная цифра должна быть три.

Если это число действительно, тогда они используют алгоритм, отличающийся от , от того, который, как вы думаете, есть.

Я думаю, что это может быть так, поскольку, когда я вставляю номер, который вы дали, на страницу трекера USPS, я вижу весь его путь.


Фактически, если вы посмотрите на публикацию 91 , Техническое руководство по службам подтверждения, вы увидите, что в нем используются две дополнительные цифры, включая 91 спереди для идентификатора приложения отслеживания. Применяя алгоритм, найденный в , который дает нам публикация :

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 для получения информации.

1 голос
/ 22 февраля 2011

Я не знаю 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('-', ''))
...