Jak mogę sprawdzić, czy ciąg znaków jest prawidłowym kodem kreskowym EAN/GTIN w kodzie JavaScript?Jak sprawdzić kod kreskowy EAN/GTIN w kodzie JavaScript
Potrzebuję czeków na EAN8, EAN12, EAN13, EAN14, EAN18, a także GTIN12, GTIN13, GTIN14.
Jak mogę sprawdzić, czy ciąg znaków jest prawidłowym kodem kreskowym EAN/GTIN w kodzie JavaScript?Jak sprawdzić kod kreskowy EAN/GTIN w kodzie JavaScript
Potrzebuję czeków na EAN8, EAN12, EAN13, EAN14, EAN18, a także GTIN12, GTIN13, GTIN14.
EDIT Stworzyłem również moduł npm, który można znaleźć pod adresem github.
Stworzyłem małą bibliotekę, która obsługuje EAN8, EAN12, EAN13, EAN14, EAN18, GTIN12, GTIN13 i GTIN14.
Działa wewnątrz pliku node.js i we wszystkich nowoczesnych przeglądarkach.
barcoder.js:
/*!
* Barcoder
* Copyright (c) 2013 mifitto GmbH <[email protected]>
* MIT Licensed
*/
(function() {
'use strict';
/**
* Library version.
*/
var version = '1.1.0';
/**
* Supported formats
*/
var minValidLength = 6;
var maxValidLength = 18;
var usualValidChars = /^\d+$/;
var formats = {
'ean8' : { validChars : /^\d+$/, validLength : 8 },
'ean12' : { validChars : /^\d+$/, validLength : 12 },
'ean13' : { validChars : /^\d+$/, validLength : 13 },
'ean14' : { validChars : /^\d+$/, validLength : 14 },
'ean18' : { validChars : /^\d+$/, validLength : 18 },
'gtin12' : { validChars : /^\d+$/, validLength : 12 },
'gtin13' : { validChars : /^\d+$/, validLength : 13 },
'gtin14' : { validChars : /^\d+$/, validLength : 14 }
};
/**
* Validates the checksum (Modulo 10)
* GTIN implementation factor 3
*
* @param {String} value The barcode to validate
* @return {Boolean}
* @api private
*/
var validateGtin = function(value) {
var barcode = value.substring(0, value.length - 1);
var checksum = parseInt(value.substring(value.length - 1), 10);
var calcSum = 0;
var calcChecksum = 0;
barcode.split('').map(function(number, index) {
number = parseInt(number, 10);
if (value.length % 2 === 0) {
index += 1;
}
if (index % 2 === 0) {
calcSum += number;
}
else {
calcSum += number * 3;
}
});
calcSum %= 10;
calcChecksum = (calcSum === 0) ? 0 : (10 - calcSum);
if (calcChecksum !== checksum) {
return false;
}
return true;
};
/**
* Barcoder class
*
* @param {string} format See formats
* @param {Object} options Valid option `enableZeroPadding`, defaults to `true`
* @api public
*/
var Barcoder = function (format, options) {
if (format && !formats[format]) throw new Error('"format" invalid');
this.format = (format) ? formats[format] : 'autoSelect';
this.options = (options) ? options : { enableZeroPadding : true };
if (!this.options.enableZeroPadding) {
this.options.enableZeroPadding = true;
}
};
/**
* Validates a barcode
*
* @param {string} barcode EAN/GTIN barcode
* @return {Boolean}
* @api public
*/
Barcoder.prototype.validate = function(barcode) {
var self = this;
if (self.format === 'autoSelect') {
if (barcode.length < minValidLength || barcode.length > maxValidLength) {
return false;
}
var isValidGtin = validateGtin(barcode);
var paddedBarcode = barcode;
var successfullyPadded = false;
if (!isValidGtin) {
var possiblyMissingZeros = maxValidLength - barcode.length;
while(possiblyMissingZeros--) {
paddedBarcode = '0' + paddedBarcode;
if (validateGtin(paddedBarcode)) {
isValidGtin = true;
successfullyPadded = true;
break;
}
}
}
return {
possibleType: (barcode.length > 8) ? 'GTIN' + barcode.length : 'EAN8/padded GTIN',
isValid: isValidGtin
};
}
var validChars = self.format.validChars;
var validLength = self.format.validLength;
var enableZeroPadding = self.options.enableZeroPadding;
if (validChars.exec(barcode) === null) {
return false;
}
if (enableZeroPadding && barcode.length < validLength) {
var missingZeros = validLength - barcode.length;
while(missingZeros--) {
barcode = '0' + barcode;
}
}
else if (!enableZeroPadding && barcode.length != validLength) {
return false;
}
else if (barcode.length > validLength) {
return false;
}
return validateGtin(barcode);
};
/**
* Export
*/
if ('undefined' !== typeof module && module.exports) {
module.exports = Barcoder;
exports.version = version;
}
if ('undefined' === typeof ender) {
this['Barcoder'] = Barcoder;
}
if ('function' === typeof define && define.amd) {
define('Barcoder', [], function() {
return Barcoder;
});
}
}).call(this);
Montaż:
$ npm install barcoder
Zastosowanie:
var Barcoder = require('barcoder');
var ean1 = '0016T20054453';
var ean2 = '9330071314999';
var validator = new Barcoder('ean13');
console.log('%s ean1 is valid: %s', ean1, validator.validate(ean1));
console.log('%s ean2 is valid: %s', ean1, validator.validate(ean2));
// or /w automatic type selection
validator = new Barcoder();
var validation1 = validator.validate(ean1);
var validation2 = validator.validate(ean2);
console.log('%s is valid: %s and has guessed type: %s', ean1, validation1.isValid, validation1.possibleType);
console.log('%s is valid: %s and has guessed type: %s', ean2, validation2.isValid, validation2.possibleType);
nie jestem pewien dlaczego, ale @mo Rozwiązanie osgummi nie działa poprawnie dla mnie. Chciałbym również obliczyć nowych kodów, a także zweryfikować starych. Skończyło się na tym, że mam weryfikowane pracować w moich przeglądarek conajmniej:
function eanCheckDigit(s){
var result = 0;
for (counter = s.length-1; counter >=0; counter--){
result = result + parseInt(s.charAt(counter)) * (1+(2*(counter % 2)));
}
return (10 - (result % 10)) % 10;
}
Oto krótka wersja, która może sprawdzić, czy cyfra EAN13 czek jest ważny:
var checkSum = ean.split('').reduce(function(p,v,i) {
return i % 2 == 0 ? p + 1 * v : p + 3 * v;
}, 0);
if (checkSum % 10 != 0) {
alert('error');
}
fajne, to dokładnie to, czego potrzebowałem, po prostu dodaj ean = "" + ean; wyślij go jako ciąg, aby użyć funkcji .split – trojan
I Przepraszam, jeśli ten kod jest trochę zbyt długo, ale to, co mam do weryfikacji jest kod kreskowy EAN13:
function isBarcode(barcode) {
if (typeof barcode === 'number') {
throw 'RuntimeError: Barcode MUST NOT be in number format'
} else if (barcode.length!==12) {
throw 'RuntimeError: String length is not 12'
};
var _= barcode.toString().split("")
var _1 = 0
var _2 = 0
var __
for ($=0;$<=10;++$) {
_1+=+_[$]
};for ($=10;$>=0;$-=2) {
_2+=+_[$]
};_2*=2
var _3 = _1+_2
__=+_3.toString().substring(1,2)
if (__>9) {
__=+_3.toString().substring(1,2)
} else if (__===0) {
__=10
};
__=10-__
if (__===+_[11]) {
return true
}
return false
};
Proszę wyjaśnij, dlaczego to działa.Dzięki temu OP nie będzie po prostu kopiował i wklejał Twojego kodu bez zrozumienia, jak to działa, lub czy w ogóle jest odpowiedni do ich zadań. – rayryeng
@rayryeng: Nie będę kopiować niczego bez pytania o uprawnienia;) Lubię sprytne rozwiązania, ale myślę, że ten fragment kodu nie jest naprawdę łatwy w utrzymaniu i/lub czytelny. Z zadowoleniem przyjmuję również wyjaśnienie. – dom
@dom - ahahaha Zgadzam się :) – rayryeng
Oto moje rozwiązanie, sprawdzając dla różnych długości kodów kreskowych wykorzystuje specyfikację obliczyć CHEC k cyfra na końcu (patrz uwaga):
// ean/gtin validation for 8, 12, 13 & 14 digit barcodes
function codeOnBlur(barcode) {
var barcodeLengthArr = [8, 12, 13, 14];
var allowedChars = new RegExp(/\d{8,14}/); // >7 & <15
// put numbers in array and convert to type Int.
var barcodeArray = barcode.split('');
for(var i = 0; i < barcodeArray.length; i++) {
barcodeArray[i] = parseInt(barcodeArray[i], 10);
}
// get the last digit for checking later
var checkDigit = barcodeArray.slice(-1)[0];
// we'll need a to compare it to this:
var remainder = 0;
// check if input (barcode) is in the array and check against the regex.
if (($.inArray(barcode.length, barcodeLengthArr) > -1) && (allowedChars.test(barcode))) {
console.log("barcodeArray ", barcodeArray, " :: checkDigit ", checkDigit);
// Pop the last item from the barcode array, test if the length is
// odd or even (see note on calculating the check digit) and
// multiply each item in array based in position:
var total = 0;
barcodeArray.pop();
// odd length after pop
if (barcodeArray.length % 2 === 1) {
for (var i = barcodeArray.length - 1; i >= 0; i--) {
barcodeArray[i] = i % 2 === 0 ? barcodeArray[i] * 3 : barcodeArray[i] * 1;
total += barcodeArray[i];
}
// even length after pop
} else if (barcodeArray.length % 2 === 0) {
for (var i = barcodeArray.length - 1; i >= 0; i--) {
barcodeArray[i] = i % 2 === 0 ? barcodeArray[i] * 1 : barcodeArray[i] * 3;
total += barcodeArray[i];
}
} else {
// validation passed = false
}
// calculate the remainder of totalrounded up to nearest multiple of 10:
remainder = (Math.ceil((total + 1)/10) * 10) - total;
console.log("loop total = ", total, ", remainder: ", remainder);
if (remainder === checkDigit) {
//validation passed = true;
return;
} else {
//validation passed = false;
}
} else {
//validation Passed = false;
}
}
jestem pewien kod ten może być uporządkowany niektóre :)
Ręczne sprawdzanie integralności „bit” lub cyfra kontrolna:
barcode: 13: 4 0 1 1 2 0 0 2 9 6 9 0 8
8: 5 0 8 1 8 9 0 7
multiplier: 3 1 3 1 3 1 3 1 3 1 3 1 check digit
Aby wziąć kod 8-cyfrowy działa wstecz:
0*1 + 9*3 + 8*1 + 1*3 + 8*1 + 0*3 + 5*1 = 73
Difference from 73 to 80 is 7 (the specification will have you round up to
the nearest power of 10).
7 jest zarówno cyfra kontrolna, a pozostała część 80-7 3.
Możesz zamienić wyrażenie Math.pow na prostsze (1+ (2 * (licznik% 2)) z tym samym wynikiem – ThunderGr
Nice! Odpowiedź zaktualizowana –
Wygląda na błąd nawiasu w wierszu czwartym. zbyt wiele, – user1876422