Skip to content

Instantly share code, notes, and snippets.

@spig
Last active May 10, 2024 15:10
Show Gist options
  • Save spig/897768 to your computer and use it in GitHub Desktop.
Save spig/897768 to your computer and use it in GitHub Desktop.
Validate a barcode UPC-E, UPC-A, EAN, EAN-14, SSCC
// checksum calculation for GTIN-8, GTIN-12, GTIN-13, GTIN-14, and SSCC
// based on http://www.gs1.org/barcodes/support/check_digit_calculator
function isValidBarcode(barcode) {
// check length
if (barcode.length < 8 || barcode.length > 18 ||
(barcode.length != 8 && barcode.length != 12 &&
barcode.length != 13 && barcode.length != 14 &&
barcode.length != 18)) {
return false;
}
var lastDigit = Number(barcode.substring(barcode.length - 1));
var checkSum = 0;
if (isNaN(lastDigit)) { return false; } // not a valid upc/ean
var arr = barcode.substring(0,barcode.length - 1).split("").reverse();
var oddTotal = 0, evenTotal = 0;
for (var i=0; i<arr.length; i++) {
if (isNaN(arr[i])) { return false; } // can't be a valid upc/ean we're checking for
if (i % 2 == 0) { oddTotal += Number(arr[i]) * 3; }
else { evenTotal += Number(arr[i]); }
}
checkSum = (10 - ((evenTotal + oddTotal) % 10)) % 10;
// true if they are equal
return checkSum == lastDigit;
}
def valid_upc(upc)
# check length
if (upc.length < 8 or upc.length > 18 or
(upc.length != 8 && upc.length != 12 &&
upc.length != 13 && upc.length != 14 &&
upc.length != 18)
)
return false
end
last_digit = upc.slice!(-1).to_i
check_sum = 0
arr = upc.split(//).reverse
odd_total = even_total = 0
arr.each_index do |i|
if (i % 2 == 0)
odd_total = odd_total + (arr[i].to_i * 3)
else
even_total = even_total + arr[i].to_i
end
end
check_sum = (10 - ((even_total + odd_total) % 10)) % 10
# true if they are equal
return check_sum == last_digit
end
@francipvb
Copy link

Also I contribute a (very) condensed python chunk to add to your gist:

def validate_length(barcode: str) -> bool:
    return len(barcode) in (8, 12, 13, 14, 18)


def validate_check_digit(barcode: str) -> bool:
    result = sum(
        i * 3 if idx % 2 == 0 else i
        for idx, i in enumerate(
            (int(i) for i in barcode),
        )
    )

    return result % 10 == 0


def validate_barcode(barcode: str) -> bool:
    return validate_length(barcode) and validate_check_digit(barcode)

Bye.

@akovia
Copy link

akovia commented Mar 15, 2023

Hi, I am trying to use this code in a Google Sheet as a custom function and I admit that I'm a bit out of my depth. I have written Bash scripts, but js is outside my wheelhouse. All my efforts so far just lead to more execution errors.

Is there any chance someone could help convert this to be used as a function in Google Sheets?
Thanks either way!

@gfsteph
Copy link

gfsteph commented May 10, 2024

The JS version does not have barcode.length != 12 at the beginning.

that only applies for a generic UPC an EAN is 13, so no the suggestion is not valid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment