Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
77.78% covered (warning)
77.78%
14 / 18
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
StringHasher
77.78% covered (warning)
77.78%
14 / 18
50.00% covered (danger)
50.00%
1 / 2
4.18
0.00% covered (danger)
0.00%
0 / 1
 hash
71.43% covered (warning)
71.43%
10 / 14
0.00% covered (danger)
0.00%
0 / 1
3.21
 hex2int
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Cognate;
4
5use InvalidArgumentException;
6use RuntimeException;
7use UtfNormal\Validator;
8
9/**
10 * BIG WARNING!!!!!   L(・o・)」
11 * Any changes in this class that result in different hashes will require all tables to be rebuilt.
12 *
13 * @license GPL-2.0-or-later
14 * @author Addshore
15 */
16class StringHasher {
17
18    /**
19     * @param string $string
20     *
21     * @throws InvalidArgumentException
22     * @throws RuntimeException if not run on a 64 bit system
23     * @return int a 64 bit SIGNED decimal hash
24     */
25    public function hash( $string ) {
26        if ( PHP_INT_SIZE !== 8 ) {
27            // 32 bit systems will result in poor hashes
28            throw new RuntimeException( 'Cognate must run on a 64bit system' );
29        }
30        if ( !is_string( $string ) ) {
31            throw new InvalidArgumentException(
32                'Tried to hash a non string value.'
33            );
34        }
35
36        $string = Validator::toNFC( $string );
37
38        return $this->hex2int(
39            substr(
40                hash( 'sha256', $string ),
41                0,
42                16
43            )
44        );
45    }
46
47    /**
48     * Replacement for the php hexdec function.
49     * hexdec( 'FFFFFFFFFFFFFFFF' ) === hexdec( 'FFFFFFFFFFFFFFF0' )
50     * There are gaps in high values that would increase the chance of collisions.
51     * So use this replacement instead.
52     *
53     * @param string $hex16
54     *
55     * @return int
56     */
57    private function hex2int( $hex16 ) {
58        $hexhi = substr( $hex16, 0, 8 );
59        $hexlo = substr( $hex16, 8, 8 );
60
61        $int = hexdec( $hexlo ) | ( hexdec( $hexhi ) << 32 );
62        return $int;
63    }
64
65}