gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
2.2KB

  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import re
  4. __all__ = ['check_barcode_encoding']
  5. def get_barcode_check_digit(numeric_barcode):
  6. """ Computes and returns the barcode check digit. The used algorithm
  7. follows the GTIN specifications and can be used by all compatible
  8. barcode nomenclature, like as EAN-8, EAN-12 (UPC-A) or EAN-13.
  9. https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
  10. https://www.gs1.org/services/how-calculate-check-digit-manually
  11. :param numeric_barcode: the barcode to verify/recompute the check digit
  12. :type numeric_barcode: str
  13. :return: the number corresponding to the right check digit
  14. :rtype: int
  15. """
  16. # Multiply value of each position by
  17. # N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 N13 N14 N15 N16 N17 N18
  18. # x3 X1 x3 x1 x3 x1 x3 x1 x3 x1 x3 x1 x3 x1 x3 x1 x3 CHECKSUM
  19. oddsum = evensum = 0
  20. code = numeric_barcode[-2::-1] # Remove the check digit and reverse the barcode.
  21. # The CHECKSUM digit is removed because it will be recomputed and it must not interfer with
  22. # the computation. Also, the barcode is inverted, so the barcode length doesn't matter.
  23. # Otherwise, the digits' group (even or odd) could be different according to the barcode length.
  24. for i, digit in enumerate(code):
  25. if i % 2 == 0:
  26. evensum += int(digit)
  27. else:
  28. oddsum += int(digit)
  29. total = evensum * 3 + oddsum
  30. return (10 - total % 10) % 10
  31. def check_barcode_encoding(barcode, encoding):
  32. """ Checks if the given barcode is correctly encoded.
  33. :return: True if the barcode string is encoded with the provided encoding.
  34. :rtype: bool
  35. """
  36. encoding = encoding.lower()
  37. if encoding == "any":
  38. return True
  39. barcode_sizes = {
  40. 'ean8': 8,
  41. 'ean13': 13,
  42. 'gtin14': 14,
  43. 'upca': 12,
  44. 'sscc': 18,
  45. }
  46. barcode_size = barcode_sizes[encoding]
  47. return (encoding != 'ean13' or barcode[0] != '0') \
  48. and len(barcode) == barcode_size \
  49. and re.match(r"^\d+$", barcode) \
  50. and get_barcode_check_digit(barcode) == int(barcode[-1])
上海开阖软件有限公司 沪ICP备12045867号-1