Skip to content
This repository has been archived by the owner on Jan 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #5 from AJenbo/patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
hanneskod committed Sep 29, 2018
2 parents c29bcc2 + cdda9ff commit 91a13a8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 62 deletions.
23 changes: 23 additions & 0 deletions src/AssertionsTrait.php
@@ -0,0 +1,23 @@
<?php

declare(strict_types = 1);

namespace byrokrat\checkdigit;

trait AssertionsTrait
{
/**
* Validate number sructure, returns number if structure is valid
*
* @throws InvalidStructureException If $number is not numerical
* @return void
*/
protected function assertNumber(string $number)
{
if (!ctype_digit($number)) {
throw new InvalidStructureException(
"Number can only contain numerical characters, found <$number>"
);
}
}
}
27 changes: 16 additions & 11 deletions src/Modulo10.php
Expand Up @@ -9,6 +9,8 @@
*/
class Modulo10 implements Calculator
{
use AssertionsTrait;

/**
* Check if the last digit of number is a valid modulo 10 check digit
*/
Expand All @@ -24,12 +26,21 @@ public function isValid(string $number): bool
*/
public function calculateCheckDigit(string $number): string
{
if (!ctype_digit($number)) {
throw new InvalidStructureException(
"Number can only contain numerical characters, found <$number>"
);
$this->assertNumber($number);

$sum = $this->calculateSum($number);

$ceil = $sum;

while ($ceil % 10 != 0) {
$ceil++;
}

return (string)($ceil-$sum);
}

protected function calculateSum(string $number): int
{
$weight = 2;
$sum = 0;

Expand All @@ -39,12 +50,6 @@ public function calculateCheckDigit(string $number): string
$weight = ($weight == 2) ? 1 : 2;
}

$ceil = $sum;

while ($ceil % 10 != 0) {
$ceil++;
}

return (string)($ceil-$sum);
return $sum;
}
}
34 changes: 4 additions & 30 deletions src/Modulo10Gtin.php
Expand Up @@ -7,42 +7,16 @@
/**
* Modulo10 calculator, variant used for GTIN (EAN, UPC, ISBN-13, JAN and ITF) barcodes
*/
class Modulo10Gtin implements Calculator
class Modulo10Gtin extends Modulo10
{
/**
* Check if the last digit of number is a valid modulo 10 check digit
*/
public function isValid(string $number): bool
protected function calculateSum(string $number): int
{
return substr($number, -1) === $this->calculateCheckDigit(substr($number, 0, -1) ?: '');
}

/**
* Calculate the modulo 10 check digit for number
*
* @throws InvalidStructureException If $number is not numerical
*/
public function calculateCheckDigit(string $number): string
{
if (!ctype_digit($number)) {
throw new InvalidStructureException(
"Number can only contain numerical characters, found <$number>"
);
}

$weight = 3;
$sum = 0;

foreach (array_reverse(str_split($number)) as $pos => $digit) {
$sum += $digit * ($pos % 2 ? 1 : $weight);
}

$ceil = $sum;

while ($ceil % 10 != 0) {
$ceil++;
$sum += $digit * ($pos % 2 ? 1 : 3);
}

return (string)($ceil-$sum);
return $sum;
}
}
6 changes: 3 additions & 3 deletions src/Modulo11.php
Expand Up @@ -9,6 +9,8 @@
*/
class Modulo11 implements Calculator
{
use AssertionsTrait;

/**
* @var array Map modulo 11 remainder to check digit
*/
Expand Down Expand Up @@ -58,9 +60,7 @@ public function isValid(string $number): bool
*/
public function calculateCheckDigit(string $number): string
{
if (!ctype_digit($number)) {
throw new InvalidStructureException("Number must consist of characters 0-9");
}
$this->assertNumber($number);

$sum = 0;

Expand Down
24 changes: 6 additions & 18 deletions src/Modulo97.php
Expand Up @@ -9,14 +9,17 @@
*/
class Modulo97 implements Calculator
{
use AssertionsTrait;

/**
* Check if the last two digits of number are valid modulo 97 check digits
*
* @throws InvalidStructureException If $number is not numerical
*/
public function isValid(string $number): bool
{
return bcmod($this->readNumber($number), '97') === '1';
$this->assertNumber($number);
return bcmod($number, '97') === '1';
}

/**
Expand All @@ -26,22 +29,7 @@ public function isValid(string $number): bool
*/
public function calculateCheckDigit(string $number): string
{
return (string)(98 - bcmod($this->readNumber($number).'00', '97'));
}

/**
* Validate number sructure, returns number if structure is valid
*
* @throws InvalidStructureException If $number is not numerical
*/
private function readNumber(string $number): string
{
if (!ctype_digit($number)) {
throw new InvalidStructureException(
"Number can only contain numerical characters, found <$number>"
);
}

return $number;
$this->assertNumber($number);
return (string)(98 - bcmod($number.'00', '97'));
}
}

0 comments on commit 91a13a8

Please sign in to comment.