Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.89% covered (warning)
88.89%
16 / 18
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Base62
88.89% covered (warning)
88.89%
16 / 18
0.00% covered (danger)
0.00%
0 / 2
7.07
0.00% covered (danger)
0.00%
0 / 1
 encode
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
4.02
 decode
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
3.01
1<?php
2
3/**
4 * Base62 generator
5 *
6 * Class to encode and decode numbers using base62
7 *
8 * PHP version 8
9 *
10 * Copyright (C) Villanova University 2020.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2,
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 *
25 * @category VuFind
26 * @package  VuFind\Crypt
27 * @author   Cornelius Amzar <cornelius.amzar@bsz-bw.de>
28 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
29 * @link     https://vufind.org/wiki/development Wiki
30 */
31
32namespace VuFind\Crypt;
33
34use Exception;
35
36use function intval;
37use function strlen;
38
39/**
40 * Base62 generator
41 *
42 * Class to encode and decode numbers using base62
43 *
44 * @category VuFind
45 * @package  Crypt
46 * @author   Cornelius Amzar <cornelius.amzar@bsz-bw.de>
47 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
48 * @link     https://vufind.org/wiki/development Wiki
49 */
50class Base62
51{
52    public const BASE62_ALPHABET
53        = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
54    public const BASE62_BASE = 62;
55
56    /**
57     * Common base62 encoding function.
58     * Implemented here so we don't need additional PHP modules like bcmath.
59     *
60     * @param string $base10Number Number to encode
61     *
62     * @return string
63     *
64     * @throws Exception
65     */
66    public function encode($base10Number)
67    {
68        $binaryNumber = intval($base10Number);
69        if ($binaryNumber === 0) {
70            throw new Exception('not a base10 number: "' . $base10Number . '"');
71        }
72
73        $base62Number = '';
74        while ($binaryNumber != 0) {
75            $base62Number = self::BASE62_ALPHABET[$binaryNumber % self::BASE62_BASE]
76                . $base62Number;
77            $binaryNumber = intdiv($binaryNumber, self::BASE62_BASE);
78        }
79
80        return ($base62Number == '') ? '0' : $base62Number;
81    }
82
83    /**
84     * Common base62 decoding function.
85     * Implemented here so we don't need additional PHP modules like bcmath.
86     *
87     * @param string $base62Number Number to decode
88     *
89     * @return int
90     *
91     * @throws Exception
92     */
93    public function decode($base62Number)
94    {
95        $binaryNumber = 0;
96        for ($i = 0; $i < strlen($base62Number); ++$i) {
97            $digit = $base62Number[$i];
98            $strpos = strpos(self::BASE62_ALPHABET, $digit);
99            if ($strpos === false) {
100                throw new Exception('not a base62 digit: "' . $digit . '"');
101            }
102
103            $binaryNumber *= self::BASE62_BASE;
104            $binaryNumber += $strpos;
105        }
106        return $binaryNumber;
107    }
108}