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

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

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

Номер проверяется с использованием кода USS 128, как описано в разделе 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 правильно определяет номер как есть, поэтому я могу только предположить, что делаю что-то не так.


person Jeff Keen    schedule 22.02.2011    source источник


Ответы (2)


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

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

person paxdiablo    schedule 22.02.2011
comment
Я думаю, вы получили это paxdiablo! классное устранение неполадок! - person jcomeau_ictx; 22.02.2011
comment
почему кто-то проголосовал за это? ответ paxdiablo почти наверняка правильный. - person jcomeau_ictx; 22.02.2011
comment
Да! Большое вам спасибо за вашу помощь. - person Jeff Keen; 22.02.2011
comment
Это также помогло мне. Спасибо! - person John Gietzen; 30.05.2012
comment
Спасибо за полезную информацию. На данный момент эта информация перемещена в Раздел 9.0 Приложение E СПЕЦИФИКАЦИИ штрих-кода, посылки, Intelligent Mail® USPS2000508 CAGE CODE 27085, который в настоящее время можно найти по адресу postalpro.usps.com/mnt/glusterfs/2018-02/ - person Chaim Geretz; 22.09.2020

Я не знаю 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('-', ''))
person jcomeau_ictx    schedule 22.02.2011
comment
хм, возможно, вы правы, я также получаю в сумме 187, что означает контрольную цифру 3. - person jcomeau_ictx; 22.02.2011
comment
Я разместил его на своей странице в Facebook, надеюсь, один из моих приятелей USPS сможет дать вам ответ. Много лет назад я работал техником по электронике в USPS, но это не было одной из спецификаций штрих-кода, с которыми мне приходилось иметь дело. - person jcomeau_ictx; 22.02.2011
comment
К вашему сведению: умножение каждого числа на 3 и последующее сложение результата — это то же самое, что сложение всех чисел вместе с последующим умножением суммы на 3. Это называется распределительным свойством. - person Jeff Keen; 22.02.2011
comment
спасибо, jeffxl, я в курсе; но неправильно прочитал ваш код и подумал, что вы умножаете накопленную сумму на 3 для каждого четного числа. Я не стал исправлять свой комментарий, потому что был занят решением проблемы. - person jcomeau_ictx; 22.02.2011
comment
Спасибо за сценарий. Обратите внимание, чтобы запустить его в Python 3, вы должны заключить в скобки аргумент для печати, так как это функция, иначе он вызовет SyntaxError: недопустимый синтаксис. print (check(''.join(sys.argv[1:]).replace('-', ''))) - person Jay; 25.12.2020
comment
В моем коде и даже в моем анализе много ошибок, учитывая ассоциативное свойство сложения и умножения, т. е. 3(a + b + c) — это то же самое, что 3a + 3b + 3c. Рад, что это помогло вам. - person jcomeau_ictx; 26.12.2020