@@ -106,24 +106,46 @@ def make_upce_barcode(numbersystem, manufacturer, product):
106106 return upc + str (checksum )
107107
108108
109+ _UPCE_RE = re .compile (r"^([01])(\d)(\d)(\d)(\d)(\d)(\d)(\d)$" )
110+
109111def convert_barcode_from_upce_to_upca (upc ):
110- upc = str (upc ).zfill (8 ) # Zero-pad to 8 digits if needed
111- if len (upc ) != 8 or not re .match (r"^[01]" , upc ):
112+ upc = str (upc ).strip ().zfill (8 )
113+
114+ m = _UPCE_RE .match (upc )
115+ if not m :
112116 return False
117+
113118 if not upcean .validate .validate_upce_checksum (upc ):
114119 return False
115-
116- upc_matches = re .match ("(0|1)(\\ d{1})(\\ d{1})(\\ d{1})(\\ d{1})(\\ d{1})(\\ d)(\\ d)" , upc ).groups ()
117- base = upc_matches [0 ] + upc_matches [1 ] + upc_matches [2 ]
118-
119- if upc_matches [6 ] in "012" :
120- upca = "{}0000{}{}" .format (base , upc_matches [3 ], upc_matches [4 ])
121- elif upc_matches [6 ] == "3" :
122- upca = "{}00000{}" .format (base , upc_matches [4 ])
123- else :
124- upca = "{}0000{}" .format (upc_matches [0 ] + upc_matches [1 ] + upc_matches [2 ] + upc_matches [3 ] + upc_matches [4 ], upc_matches [6 ])
125-
126- return upca + upc_matches [7 ]
120+
121+ ns , d1 , d2 , d3 , d4 , d5 , d6 , chk = m .groups ()
122+
123+ if d6 in "012" :
124+ mfg = d1 + d2 + d6 + "00" # FIXED (5 digits)
125+ item = "00" + d3 + d4 + d5 # 5 digits
126+ elif d6 == "3" :
127+ mfg = d1 + d2 + d3 + "00" # 5 digits
128+ item = "000" + d4 + d5 # 5 digits
129+ elif d6 == "4" :
130+ mfg = d1 + d2 + d3 + d4 + "0" # 5 digits
131+ item = "0000" + d5 # 5 digits
132+ else : # 5-9
133+ mfg = d1 + d2 + d3 + d4 + d5 # 5 digits
134+ item = "0000" + d6 # 5 digits
135+
136+ upca11 = ns + mfg + item
137+ if len (upca11 ) != 11 :
138+ return False
139+
140+ upca12 = upca11 + chk
141+ if len (upca12 ) != 12 :
142+ return False
143+
144+ if not upcean .validate .validate_upca_checksum (upca12 ):
145+ return False
146+
147+ return upca12
148+
127149
128150def convert_barcode_from_upca_to_ean13 (upc ):
129151 upc = str (upc ).zfill (12 )
@@ -164,18 +186,31 @@ def convert_barcode_from_upca_to_upce(upc):
164186 if len (upc ) != 12 or not upcean .validate .validate_upca_checksum (upc ):
165187 return False
166188
167- patterns = [
168- ("(0|1)(\\ d{2})00000(\\ d{3})(\\ d{1})" , "{}{}{}0{}" ),
169- ("(0|1)(\\ d{3})00000(\\ d{2})(\\ d{1})" , "{}{}{}3{}" ),
170- ("(0|1)(\\ d{4})00000(\\ d{1})(\\ d{1})" , "{}{}{}4{}" ),
171- ("(0|1)(\\ d{5})00005(\\ d{1})" , "{}{}5{}" ),
172- ]
173-
174- for pattern , fmt in patterns :
175- match = re .match (pattern , upc )
176- if match :
177- return fmt .format (* match .groups ())
178-
189+ ns = upc [0 ]
190+ if ns not in "01" :
191+ return False
192+
193+ mfg = upc [1 :6 ] # 5 digits
194+ prod = upc [6 :11 ] # 5 digits
195+ chk = upc [11 ]
196+
197+ # UPC-E "mode" 0,1,2
198+ if mfg [2 ] in "012" and mfg [3 :5 ] == "00" and prod [0 :2 ] == "00" :
199+ # NS + (mfg[0:2]) + (prod[2:5]) + (mfg[2]) + check
200+ return (ns + mfg [0 :2 ] + prod [2 :5 ] + mfg [2 ] + chk ).zfill (8 )
201+
202+ # mode 3
203+ if mfg [3 :5 ] == "00" and prod [0 :3 ] == "000" :
204+ return (ns + mfg [0 :3 ] + prod [3 :5 ] + "3" + chk ).zfill (8 )
205+
206+ # mode 4
207+ if mfg [4 ] == "0" and prod [0 :4 ] == "0000" :
208+ return (ns + mfg [0 :4 ] + prod [4 ] + "4" + chk ).zfill (8 )
209+
210+ # mode 5-9
211+ if prod [0 :4 ] == "0000" and prod [4 ] in "56789" :
212+ return (ns + mfg + prod [4 ] + chk ).zfill (8 )
213+
179214 return False
180215
181216def convert_barcode_from_ean13_to_upce (upc ):
0 commit comments