Validate EAN13 Barcodes

30th April 2009 - 4 minutes read time

EAN13 barcodes are commonly used to label products in Europe. If you want to know more about how they work then please view the Wikipedia entry on European Article Numbers.

EAN13 barcodes are actually 12 digits long and are validated by using a check digit, which is placed at the end, making the code 13 digits long. The check digit is worked out by the following process:

  • Add up all of the even numbers and multiply this number by 3.
  • Add up all of the odd numbers and add this result to the result of the even numbers.
  • Divide the number by 10 and keep the remainder (modulo).
  • If the remainder is not 0 then subtract 10 from this number.

Here is a function that runs through those steps, but also check to see what length the barcode is. If it is 13 digits long then it returns both the original check digit and the calculated check digit. If the barcode is 12 digits long then it returns the checksum. In both cases the original barcode is also returned.

  1. function validateEan13($digits)
  2. {
  3. $originalcheck = false;
  4. if ( strlen($digits) == 13 ) {
  5. $originalcheck = substr($digits, -1);
  6. $digits = substr($digits, 0, -1);
  7. } elseif ( strlen($digits) != 12 ) {
  8. // Invalid EAN13 barcode
  9. return false;
  10. }
  11.  
  12. // Add even numbers together
  13. $even = $digits[1] + $digits[3] + $digits[5] + $digits[7] + $digits[9] + $digits[11];
  14. // Multiply this result by 3
  15. $even = $even * 3;
  16.  
  17. // Add odd numbers together
  18. $odd = $digits[0] + $digits[2] + $digits[4] + $digits[6] + $digits[8] + $digits[10];
  19.  
  20. // Add two totals together
  21. $total = $even + $odd;
  22.  
  23. // Calculate the checksum
  24. // Divide total by 10 and store the remainder
  25. $checksum = $total % 10;
  26. // If result is not 0 then take away 10
  27. if($checksum != 0){
  28. $checksum = 10 - $checksum;
  29. }
  30.  
  31. // Return results.
  32. if ( $originalcheck !== false ) {
  33. return array('barcode'=>$digits, 'checksum'=>$checksum, 'originalcheck'=>$originalcheck);
  34. } else {
  35. return array('barcode'=>$digits, 'checksum'=>$checksum);
  36. }
  37. }

To test this I ran a few codes through the function.

  1. // two normal barcodes
  2. print_r(validateEan13(5023920187205));
  3. print_r(validateEan13(5010548001860));
  4. // one short barcode to work out checksum
  5. print_r(validateEan13(501054800186));
  6. // a normal barcode
  7. print_r(validateEan13(5034504935778));
  8. // the same barcode with a broken number
  9. print_r(validateEan13(5034504735778));
  10. // two random numbers, one of which is not long enough to be an EA13 barcode
  11. print_r(validateEan13(7233897438712));
  12. var_dump(validateEan13(3345345345));

This prints out the following results, which I have annotated for your convenience.

  1. // two normal barcodes
  2. Array
  3. (
  4. [barcode] => 502392018720
  5. [checksum] => 5
  6. [originalcheck] => 5
  7. )
  8. Array
  9. (
  10. [barcode] => 501054800186
  11. [checksum] => 0
  12. [originalcheck] => 0
  13. )
  14. // one short barcode to work out checksum
  15. Array
  16. (
  17. [barcode] => 501054800186
  18. [checksum] => 0
  19. )
  20.  
  21. // a normal barcode
  22. Array
  23. (
  24. [barcode] => 503450493577
  25. [checksum] => 8
  26. [originalcheck] => 8
  27. )
  28. // the same barcode with a broken number
  29. Array
  30. (
  31. [barcode] => 503450473577
  32. [checksum] => 4
  33. [originalcheck] => 8
  34. )
  35. // two random numbers, one of which is not long enough to be an EA13 barcode
  36. Array
  37. (
  38. [barcode] => 723389743871
  39. [checksum] => 4
  40. [originalcheck] => 2
  41. )
  42. bool(false)

Add new comment

The content of this field is kept private and will not be shown publicly.