Socket
Socket
Sign inDemoInstall

@ericblade/barcode-validator

Package Overview
Dependencies
0
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0 to 2.4.0

.vscode/settings.json

128

index.js

@@ -0,1 +1,5 @@

// Useful information: GTIN13 and EAN are basically the same thing.
// TODO: should also be functions to convert between UPC and EAN.
// TODO: need to also return 978 and 979 versions of 290 and 291 series ISBN barcodes.
/* eslint-disable eqeqeq */

@@ -8,2 +12,16 @@ const validationRegex = /^(\d{8,14}|\d{9}[xX])$/;

// generates a checksum calculator. The various checksums we support are all generated in similar
// fashion, just using some slightly different parameters. In UPC, odd numbers are multiplied by 3,
// in GTIN and ISBN, the even numbers are multiplied by 3. The difference between ISBN and GTIN checksums
// is that GTIN checksums are calculated from last digit to first, instead of first to last.
// Therefore, we have 3 function parameters: evenMult, oddMult, and shouldReverse. The formulae are
// otherwise identical between UPC, GTIN, and ISBN. This may also be true for other types of barcodes,
// but I have not studied those, as these are the most commonly used ones in the United States, where I am
// located. -Eric
// The returned function takes a string containing numbers from 0-9, and calculates a checksum value.
// Note that it does NOT validate that the length of the string is valid -- it returns a checksum based
// on the entire string given to it, it needs to be up to other functions to determine if the length
// is valid or not.
// Note also that ISBN10, which contains "X" as a valid character, has a completely different checksum
// routine, below.
const generateChecksumCalculator = ({ evenMult, oddMult, shouldReverse }) => {

@@ -30,2 +48,3 @@ return (str) => {

// create the UPC, ISBN13, and GTIN checksum generators.
// ([ a, b, c, d, e, f, g, h, i, j, k ] * [ 3 1 3 1 3 1 3 1 3 1 3 1 ]) % 10

@@ -38,2 +57,3 @@ const getUpcChecksum = generateChecksumCalculator({ evenMult: 1, oddMult: 3, shouldReverse: false });

// all of the supported barcode types have their checksum digit as the last digit of the string.
const extractCheckDigit = (code) => {

@@ -77,43 +97,87 @@ const str = code.toString().toUpperCase();

// https://stackoverflow.com/questions/2123131/determine-if-10-digit-string-is-valid-amazon-asin
// effectively tells us "does this string start with a "B" and is 10 alpha-numeric digits.
// Unfortunately, 10 digit strings such as BOOTSTRAPS look like a perfectly valid ASIN, and you wouldn't
// know the difference without asking Amazon if it's real.
const validAsin = (asin) => {
return /^(B[\dA-Z]{9}|\d{9}(X|\d))$/.test(asin);
}
function getTypeOfBarcode(code) {
switch(code.length) {
case 10: {
if (code.startsWith('B')) {
return 'asin';
}
return 'isbn10';
}
case 12: return 'upc';
case 13: {
if(/^(978|979|290|291)[0-9].*/.test(code)) {
return 'isbn13';
}
return 'gtin';
}
default: return 'gtin';
}
}
const validatorMap = {
gtin: validGtinChecksum,
upc: validUpcChecksum,
isbn10: validIsbn10Checksum,
isbn13: validIsbn13Checksum,
asin: validAsin,
};
// Given a barcode and an optional type, will attempt to correct an invalid code in some possible ways,
// and return if the code was valid. If a type is NOT provided, type will be inferred (see getTypeOfBarcode())
// and returned. If you DO specify a type, *only* validation on that type will be performed.
// Therefore, if your application *requires* a ISBN, pass the type. If your application doesn't care what
// kind, or wants to know what kind it is, then don't pass the type.
// From the return value, you probably want to make use of the modifiedCode value, as that will contain
// the barcode that was actually validated -- ancient UPC codes pre-12 digit usage will be modified,
// if passed a "used" book code of 290 or 291, modifiedCode will contain the 978/979 bookland version.
const validate = (code, type) => {
// 1980s era UPC codes were apparently 11 digits, not using a checksum. So, if we get 11, I
// guess there's not much we can do?
// TODO: we might want to re-architect this so it can pass the corrected UPC back to the caller
// if (code.length === 11) code = `${code}${getUpcChecksum(code)}`;
// if (code.length === 11) code = `0${code}`;
if (code.length === 11) code = `11 digit upc not valid`;
// guess there's not much we can do besides pass it with a 0 prefixing it and hope it works.
const modifiedCode = code.length === 11 ? `0${code}` : code;
if (!type) {
type = (function determineType(t) {
switch(t.length) {
case 10: return 'isbn10';
case 12: return 'upc';
case 13: {
if (code.startsWith('978') || code.startsWith('979') || code.startsWith('290') || code.startsWith('291')) {
return 'isbn13';
}
return 'gtin';
}
default: return 'gtin';
}
})(code);
type = getTypeOfBarcode(modifiedCode);
}
// console.warn('* validating ', code, type);
if (validationRegex.exec(code) === null) {
return false;
// console.warn('* validating ', code, modifiedCode, type);
if (type === 'isbn13') {
if (modifiedCode.startsWith('290')) {
const [ junk1, junk2, junk3, ...rest ] = modifiedCode;
const baseCode = rest.join('');
modifiedCode = `978${baseCode}${getIsbn13Checksum(`978${baseCode}`)}`;
} else if (modifiedCode.startsWith('291')) {
const [ junk1, junk2, junk3, ...rest ] = modifiedCode;
const baseCode = rest.join('');
modifiedCode = `979${baseCode}${getIsbn13Checksum(`979${baseCode}`)}`
}
}
if (type === 'gtin') {
return validGtinChecksum(code);
let valid = false;
if (type !== 'asin' && !validationRegex.test(modifiedCode)) {
type = 'unknown';
} else {
valid = validatorMap[type](modifiedCode);
}
if (type === 'upc') {
return validUpcChecksum(code);
return {
code,
type,
valid,
modifiedCode,
}
if (type === 'isbn10') {
return validIsbn10Checksum(code);
}
if (type === 'isbn13') {
return validIsbn13Checksum(code);
}
}
// console.warn(validate('092091900451'));
// console.warn(validate('092091900451')); // valid UPC
// console.warn(validate('92091900451')); // valid old UPC
// console.warn(validate('0083717201410')); // should be a valid EAN / GTIN13
// console.warn(validate('00837172014104')); // should be a valid GTIN14 !!
// console.warn(validate('BOOTSTRA P')); // should be an invalid ASIN
// console.warn(getUpcChecksum('02035616631'));
// console.warn(validate('Test random text'));
module.exports = validate;
{
"name": "@ericblade/barcode-validator",
"version": "1.0.0",
"version": "2.4.0",
"description": "Node Javascript Barcode Validation for ISBN10, ISBN13, UPC, GTIN",
"main": "index.js",
"main": "./index.js",
"types": "./index.d.ts",
"scripts": {

@@ -7,0 +8,0 @@ "test": "echo \"Error: no test specified\" && exit 1"

# barcode-validator
Simple Javascript nodejs barcode validation for ISBN10, ISBN13, UPC, GTIN
Usage:
````
> const barcodeValidator = require('@ericblade/barcode-validator');
undefined
> barcodeValidator('092091900451');
true
> barcodeValidator('092091900452');
false
>
````
Javascript nodejs barcode validation for ISBN10, ISBN13, UPC, GTIN
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc