Item Master 專案的條碼品質控管參考文件。 涵蓋格式驗證、GS1 prefix 判讀、常見誤判模式與大規模驗證流程。
| 格式 | 位數 | 結構 | 常見場景 |
|---|---|---|---|
| EAN-13 | 13 | PPP MMMM IIIII C |
台灣與多數零售商品主流 |
| EAN-8 | 8 | PPPP IIIC |
小型包裝 |
| UPC-A | 12 | S MMMMM IIIII C |
北美商品,可前補 0 轉為 EAN-13 |
| GTIN-14 | 14 | I PPP MMMM IIIII C |
箱購或物流單位 |
| ISBN-13 | 13 | 978/979 + ... |
書籍,格式上與 EAN-13 相同 |
位數說明(EAN-13):
PPP:GS1 前綴MMMM:廠商碼IIIII:商品碼C:校驗碼輸入:前 12 位數字 d[0] 到 d[11]
加權求和:
sum = d[0]*1 + d[1]*3 + d[2]*1 + d[3]*3 + ... + d[11]*3
校驗碼:
check = (10 - sum % 10) % 10
驗證:check == d[12]
def validate_ean13(code: str) -> bool:
"""驗證 EAN-13 校驗碼。"""
if len(code) != 13 or not code.isdigit():
return False
total = sum(int(d) * (1 if i % 2 == 0 else 3) for i, d in enumerate(code[:12]))
check = (10 - total % 10) % 10
return check == int(code[12])輸入:前 7 位數字 d[0] 到 d[6]
加權求和:
sum = d[0]*3 + d[1]*1 + d[2]*3 + d[3]*1 + d[4]*3 + d[5]*1 + d[6]*3
校驗碼:
check = (10 - sum % 10) % 10
驗證:check == d[7]
def validate_ean8(code: str) -> bool:
"""驗證 EAN-8 校驗碼。"""
if len(code) != 8 or not code.isdigit():
return False
total = sum(int(d) * (3 if i % 2 == 0 else 1) for i, d in enumerate(code[:7]))
check = (10 - total % 10) % 10
return check == int(code[7])UPC-A 可視為前面補 0 的 EAN-13:
def validate_upc_a(code: str) -> bool:
"""驗證 UPC-A,轉為 EAN-13 後檢查。"""
if len(code) != 12 or not code.isdigit():
return False
return validate_ean13("0" + code)def validate_gtin14(code: str) -> bool:
"""驗證 GTIN-14 校驗碼。"""
if len(code) != 14 or not code.isdigit():
return False
weights = [3, 1] * 7
total = sum(int(d) * w for d, w in zip(code[:13], weights))
check = (10 - total % 10) % 10
return check == int(code[13])def validate_barcode(code: str) -> tuple[bool, str]:
"""回傳 (是否有效, 格式名稱)。"""
if not code or not code.isdigit():
return False, "invalid"
if len(code) == 13:
return validate_ean13(code), "EAN-13"
if len(code) == 8:
return validate_ean8(code), "EAN-8"
if len(code) == 12:
return validate_upc_a(code), "UPC-A"
if len(code) == 14:
return validate_gtin14(code), "GTIN-14"
return False, "invalid"格式合法不代表一定適合直接進 item master。
建議至少分成下列幾類:
471:台灣主池,可視為一般候選池核心200-299:限制流通碼或零售商內部碼,預設隔離978/979:ISBN 書碼,預設分池管理978/979
在保健、美妝、書店型通路特別容易混入。00000000、0000000000000
這類值可能通過長度與校驗邏輯,但不應保留。原始字串
↓
只保留數字
↓
檢查長度是否為 8 / 12 / 13 / 14
↓
驗證校驗碼
↓
檢查 prefix 風險
↓
檢查 佔位碼 與重複數字模式
↓
結合名稱、包裝層級、時間與來源做語義判斷
barcodebarcode_formatis_check_digit_validprefix3risk_flagssource_channelobserved_at條碼驗證至少要分成兩層:先驗格式,再驗語義。真正難的通常不是校驗碼,而是條碼是不是被用在對的商品語境裡。