Skip to content

Instantly share code, notes, and snippets.

@spig
Last active November 11, 2023 21:56
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • 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
@cebence
Copy link

cebence commented Dec 26, 2014

It fails when the check digit equals 10.
Line #24 should say:

checkSum = (10 - ((evenTotal + oddTotal) % 10)) % 10;

@tompazourek
Copy link

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

@spig
Copy link
Author

spig commented May 14, 2016

@cebence @tompazourek - thank you for your fixes.

@alphanull
Copy link

Assuming I want to use this code (seems to work fine for me): What is the license type then? Would be nice if you could clarify this.

@fromdev
Copy link

fromdev commented Jul 10, 2021

Just used this gist code in my opensource project that allows you to create & download barcode images for absolutely free. this tool will always be free. Thanks for your contribution making it possible in small time.

https://tools.fromdev.com/bar-code-generator.html

@francipvb
Copy link

Hello,

What about UPC-E barcodes?

@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!

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