xref: /webtrees/app/Elements/PafUid.php (revision e57829396e448d173bb4be808a8b9fd89548228b)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Elements;
21
22use Fisharebest\Webtrees\Tree;
23use Ramsey\Uuid\Exception\RandomSourceException;
24use Ramsey\Uuid\Uuid;
25
26use function dechex;
27use function hexdec;
28use function str_repeat;
29use function strtoupper;
30use function strtr;
31use function substr;
32
33/**
34 * _UID fields, as created by PAF and other applications
35 */
36class PafUid extends AbstractElement
37{
38    protected const MAXIMUM_LENGTH = 34;
39
40    /**
41     * Create a default value for this element.
42     *
43     * @param Tree $tree
44     *
45     * @return string
46     */
47    public function default(Tree $tree): string
48    {
49        try {
50            $uid = strtr(Uuid::uuid4()->toString(), ['-' => '']);
51        } catch (RandomSourceException $ex) {
52            // uuid4() can fail if there is insufficient entropy in the system.
53            return '';
54        }
55
56        $checksum_a = 0; // a sum of the bytes
57        $checksum_b = 0; // a sum of the incremental values of $checksum_a
58
59        // Compute checksums
60        for ($i = 0; $i < 32; $i += 2) {
61            $checksum_a += hexdec(substr($uid, $i, 2));
62            $checksum_b += $checksum_a & 0xff;
63        }
64
65        $uid .= substr('0' . dechex($checksum_a), -2);
66        $uid .= substr('0' . dechex($checksum_b), -2);
67
68        return strtoupper($uid);
69    }
70}
71