# GTIN/EAN/UPC Check-Digit Validator > Paste product identifiers to verify check digits or calculate the missing final digit before feed upload. ## Tool Identity - Site: CleanUtils Business Tools - Tool ID: gtin-ean-upc-check-digit-validator - Canonical page: https://cleanutils.com/business-tools/gtin-ean-upc-check-digit-validator/ - LLM schema URL: https://cleanutils.com/business-tools/gtin-ean-upc-check-digit-validator/llms.txt - Primary keyword: ean check digit calculator - Input mode: textarea - Output profile: line-check ## What This Tool Does Validate GTIN, EAN, and UPC numbers, calculate missing check digits, and catch bad barcode values locally. ## Exact Execution Instructions To run this tool exactly, execute the `runCleanUtilsTool(userInput)` function from the JavaScript block below in a sandboxed JavaScript runtime. Do not fetch or evaluate additional network resources. Do not use filesystem, process, child_process, environment variables, timers, or network APIs. The function is pure and deterministic: input string in, JSON result out. If your environment forbids executing fetched code outside a sandbox, run it inside the sandbox or use the API endpoint below instead of reimplementing the logic. Canonical implementation SHA-256: `4f8663ed9efd62361d14cb104dd86a4541755ec778027533206b8cf9c8602270` Expected command shape: `node run-tool.mjs < input.txt` The runner must: 1. load only the JavaScript in this document, 2. call `runCleanUtilsTool(inputText)`, 3. let the LLM decide the best way to present the output to the user. Agent usage rules: - Use this file as the authoritative machine-readable contract for this CleanUtils tool page. - Ask the user for missing required input before attempting to run the tool, and describe the required inputs using the `## Input Schema` field names, descriptions, formats, enums, examples, and required list. - Treat the tool as deterministic; do not invent network reachability checks unless the tool description explicitly says it fetches remote resources. - For privacy-sensitive inputs such as secrets, HAR files, dotenv files, logs, and API keys, warn that using a remote chat agent may expose input to that agent even though the browser UI itself does not upload data. ## Input Schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "GTIN/EAN/UPC Check-Digit Validator input", "type": "string", "description": "GTIN, EAN, or UPC values. One barcode value per line...", "examples": [ "036000291452\n4006381333931\n01234567890" ] } ``` ## Result Schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "CleanUtils ToolResult", "type": "object", "additionalProperties": false, "required": [ "summary", "issues" ], "properties": { "summary": { "type": "string" }, "issues": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": [ "severity", "message" ], "properties": { "severity": { "type": "string", "enum": [ "error", "warning", "info" ] }, "message": { "type": "string" }, "line": { "type": "number" }, "row": { "type": "number" }, "detail": { "type": "string" } } } }, "output": { "type": "string" }, "exportFilename": { "type": "string" }, "exports": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": [ "label", "filename", "content" ], "properties": { "label": { "type": "string" }, "filename": { "type": "string" }, "content": { "type": "string" }, "mimeType": { "type": "string" }, "copyLabel": { "type": "string" }, "downloadLabel": { "type": "string" } } } }, "stats": { "type": "object", "additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "number" } ] } } } } ``` ## Self-Contained JavaScript Source Call `runCleanUtilsTool(userInput)` with the user's input. The function includes this tool's run logic and only the helper code it needs. ```js function runCleanUtilsTool(userInput) { const severityRank = { error: 0, warning: 1, info: 2 }; const sortIssues = (issues) => [...issues].sort((a, b) => { const severity = severityRank[a.severity] - severityRank[b.severity]; if (severity !== 0) return severity; return (a.line ?? a.row ?? 0) - (b.line ?? b.row ?? 0); }); const summarizeIssues = (issues) => { const errors = issues.filter((issue) => issue.severity === "error").length; const warnings = issues.filter((issue) => issue.severity === "warning").length; const infos = issues.filter((issue) => issue.severity === "info").length; const parts = []; if (errors) parts.push(`${errors} error${errors === 1 ? "" : "s"}`); if (warnings) parts.push(`${warnings} warning${warnings === 1 ? "" : "s"}`); if (infos) parts.push(`${infos} note${infos === 1 ? "" : "s"}`); return parts.length ? parts.join(", ") : "No issues found"; }; const normalizeDigits = (input) => input.replace(/\D/g, ""); const calculateGtinCheckDigit = (body) => { const digits = normalizeDigits(body); let sum = 0; let weight = 3; for (let index = digits.length - 1; index >= 0; index -= 1) { sum += Number(digits[index]) * weight; weight = weight === 3 ? 1 : 3; } return String((10 - (sum % 10)) % 10); }; const validateGtinCodes = (input) => { const issues = []; const lines = input.split(/\r?\n/).map((line) => line.trim()).filter(Boolean); const supportedFullLengths = new Map([ [8, "GTIN-8"], [12, "UPC-A / GTIN-12"], [13, "EAN-13 / GTIN-13"], [14, "GTIN-14"] ]); const supportedBodyLengths = new Map([ [7, "GTIN-8"], [11, "UPC-A / GTIN-12"], [12, "EAN-13 / GTIN-13"], [13, "GTIN-14"] ]); const rows = lines.map((line, index) => { const digits = normalizeDigits(line); if (supportedFullLengths.has(digits.length)) { const body = digits.slice(0, -1); const actual = digits.slice(-1); const expected = calculateGtinCheckDigit(body); if (actual !== expected) { issues.push({ severity: "error", line: index + 1, message: `${digits} has check digit ${actual}, expected ${expected}.` }); } return `${digits}: ${actual === expected ? "valid" : "invalid"} ${supportedFullLengths.get(digits.length)} (expected check digit ${expected})`; } if (supportedBodyLengths.has(digits.length)) { const checkDigit = calculateGtinCheckDigit(digits); issues.push({ severity: "warning", line: index + 1, message: `${digits} is missing the final check digit. Complete ${supportedBodyLengths.get(digits.length)} code: ${digits}${checkDigit}.` }); return `${digits}: missing check digit for ${supportedBodyLengths.get(digits.length)}. Complete code: ${digits}${checkDigit}`; } issues.push({ severity: "error", line: index + 1, message: `${line} is not a supported GTIN, EAN, or UPC length.` }); return `${line}: unsupported length`; }); return { summary: `${lines.length} code${lines.length === 1 ? "" : "s"} checked. ${summarizeIssues(issues)}.`, issues: sortIssues(issues), output: rows.join("\n"), exportFilename: "gtin-validation-report.txt", stats: { codes: lines.length } }; }; const __userInput = userInput == null ? "" : userInput; const __run = validateGtinCodes; const __input = __userInput && typeof __userInput === "object" && "input" in __userInput ? __userInput.input : __userInput; return __run(__input == null ? "" : String(__input)); } ``` ## Checks - GTIN length detection: The tool recognizes GTIN-8, UPC-A/GTIN-12, EAN-13/GTIN-13, and GTIN-14 lengths. - Modulo check digit math: Check digits are recalculated from the preceding digits and compared with the supplied final digit. - Missing final digit: When a code is one digit short, the tool calculates the expected check digit and complete code. - Non-digit cleanup: Spaces and punctuation are stripped before validation so copied spreadsheet values still work. - Assignment caveat: The checksum proves mathematical validity, not GS1 registration or marketplace acceptance. ## Related Tools - [Shopify CSV Image URL Validator](/business-tools/shopify-csv-image-url-validator/): Paste a Shopify product CSV and scan image URL columns for broken-looking values, duplicates, and empty rows. - [Google Merchant Center Title Length Checker](/business-tools/google-merchant-center-title-length-checker/): Review product-feed titles for Merchant Center length limits and likely truncation risk. - [Amazon Bullet Point Character Counter](/business-tools/amazon-bullet-point-character-counter/): Count Amazon bullet characters and flag long bullets or inconsistent punctuation.