Calculate check digit for machine/component ID, warn public users of typos

master
Skylar Ittner 4 years ago
parent 1866b59040
commit b52f0b0eb3

@ -0,0 +1,48 @@
<?php
/*
* Copyright 2020 Netsyms Technologies.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
class CheckDigit {
/**
* https://en.wikipedia.org/wiki/S10_(UPU_standard)#Check-digit_calculation
* @param $number 8-digit number (int or string). Digits to the right of the eighth are ignored
* when calculating the checksum.
* @return int
*/
public static function S10($number): int {
$weights = [8, 6, 4, 2, 3, 5, 9, 7];
$sum = 0;
$digits = str_split(str_pad("$number", 8, "0", STR_PAD_LEFT));
for ($i = 0; $i < 8; $i++) {
$sum += $digits[$i] * $weights[$i];
}
$sum = 11 - ($sum % 11);
if ($sum == 10) {
$sum = 0;
} else if ($sum == 11) {
$sum = 5;
}
return $sum;
}
/**
* Check if the given number has a valid S10 check digit at index 8 (ninth counting from 1).
* @param type $number
* @return bool
*/
public static function validateS10($number): bool {
$numberpad = str_pad("$number", 9, "0", STR_PAD_LEFT);
$digits = str_split($numberpad);
$realcheckdigit = CheckDigit::S10($number);
return ($digits[8] == $realcheckdigit);
}
}

@ -231,17 +231,22 @@ class Component implements JsonSerializable {
/**
* Generate a random ID number that is not in use.
* Default: 681######
* Default: 681#####[check digit]
* @global $database
* @param int $min Optional minimum number.
* @param int $max Optional maximum number.
* @return int
*/
public static function generateId(int $min = 681000000, int $max = 681999999): int {
public static function generateId(int $min = 68100000, int $max = 68199999): int {
global $database;
do {
$id = random_int($min, $max);
// If default gen add check digit
if ($id >= 68100000 && $id <= 68199999) {
$id = ("$id" . CheckDigit::S10($id)) * 1;
}
} while ($database->has('components', ['compid' => $id]) || $database->has('machines', ['machineid' => $id]));
return $id;

@ -281,17 +281,22 @@ class Machine implements JsonSerializable {
/**
* Generate a random ID number that is not in use.
* Default: 680[1-3]######
* Default: 680#####[check digit]
* @global $database
* @param int $min Optional minimum number.
* @param int $max Optional maximum number.
* @return int
*/
public static function generateId(int $min = 680100000, int $max = 680399999): int {
public static function generateId(int $min = 68010000, int $max = 68099999): int {
global $database;
do {
$id = random_int($min, $max);
// If default gen add check digit
if ($id >= 68010000 && $id <= 68039999) {
$id = ("$id" . CheckDigit::S10($id)) * 1;
}
} while ($database->has('machines', ['machineid' => $id]) || $database->has('components', ['compid' => $id]));
return $id;

@ -36,7 +36,36 @@ if (isset($_GET["backgroundcolor"]) && !empty($_GET["backgroundcolor"]) && preg_
<div class="row justify-content-center">
<div class="<?php if (!isset($_GET["embed"])) { ?>col-12 col-md-8<?php } else { ?>col-12<?php } ?>">
<?php
if (empty($_GET["id"]) || (!Machine::exists($_GET["id"]) && !Machine::serialExists($_GET["id"]))) {
if (!empty($_GET["id"]) && strpos($_GET["id"], "68") === 0 && !CheckDigit::validateS10($_GET["id"])) {
// Made a typo in the machine ID
?>
<div class="card">
<h3 class="card-header d-flex">
<div>
<i class="fas fa-desktop"></i> <?php $Strings->get("Device Info"); ?>
</div>
</h3>
<div class="card-body">
<?php
if (!empty($_GET["id"])) {
?>
<p class="text-danger"><code><?php echo htmlspecialchars($_GET['id']); ?></code> is not valid. Please try re-typing it.</p>
<?php
}
?>
<?php if (!isset($_GET["embed"])) { ?>
<p>
Enter a <?php echo $SETTINGS["branding"]["machineidnumber"]; ?>, serial number, or tracking code.
</p>
<form method="GET">
<input type="text" name="id" class="form-control" placeholder="Number" required />
<button type="submit" class="btn btn-primary btn-block mt-2">Get Info</button>
</form>
<?php } ?>
</div>
</div>
<?php
} else if (empty($_GET["id"]) || (!Machine::exists($_GET["id"]) && !Machine::serialExists($_GET["id"]))) {
// try package tracking query
$trackingok = false;
if (!empty($_GET["id"]) && preg_match("/^[a-z0-9]{10,}$/", $_GET["id"])) {

Loading…
Cancel
Save