Calculate check digit for machine/component ID, warn public users of typos
This commit is contained in:
parent
1866b59040
commit
b52f0b0eb3
48
lib/CheckDigit.lib.php
Normal file
48
lib/CheckDigit.lib.php
Normal file
@ -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.
|
* Generate a random ID number that is not in use.
|
||||||
* Default: 681######
|
* Default: 681#####[check digit]
|
||||||
* @global $database
|
* @global $database
|
||||||
* @param int $min Optional minimum number.
|
* @param int $min Optional minimum number.
|
||||||
* @param int $max Optional maximum number.
|
* @param int $max Optional maximum number.
|
||||||
* @return int
|
* @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;
|
global $database;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$id = random_int($min, $max);
|
$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]));
|
} while ($database->has('components', ['compid' => $id]) || $database->has('machines', ['machineid' => $id]));
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
|
@ -281,17 +281,22 @@ class Machine implements JsonSerializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a random ID number that is not in use.
|
* Generate a random ID number that is not in use.
|
||||||
* Default: 680[1-3]######
|
* Default: 680#####[check digit]
|
||||||
* @global $database
|
* @global $database
|
||||||
* @param int $min Optional minimum number.
|
* @param int $min Optional minimum number.
|
||||||
* @param int $max Optional maximum number.
|
* @param int $max Optional maximum number.
|
||||||
* @return int
|
* @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;
|
global $database;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$id = random_int($min, $max);
|
$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]));
|
} while ($database->has('machines', ['machineid' => $id]) || $database->has('components', ['compid' => $id]));
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
|
@ -36,7 +36,36 @@ if (isset($_GET["backgroundcolor"]) && !empty($_GET["backgroundcolor"]) && preg_
|
|||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="<?php if (!isset($_GET["embed"])) { ?>col-12 col-md-8<?php } else { ?>col-12<?php } ?>">
|
<div class="<?php if (!isset($_GET["embed"])) { ?>col-12 col-md-8<?php } else { ?>col-12<?php } ?>">
|
||||||
<?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
|
// try package tracking query
|
||||||
$trackingok = false;
|
$trackingok = false;
|
||||||
if (!empty($_GET["id"]) && preg_match("/^[a-z0-9]{10,}$/", $_GET["id"])) {
|
if (!empty($_GET["id"]) && preg_match("/^[a-z0-9]{10,}$/", $_GET["id"])) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user