Completed
Push — master ( ad6a51...9bf526 )
by Levan
02:18
created

GoogleTokenGenerator::TL()   D

Complexity

Conditions 9
Paths 20

Size

Total Lines 36
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 36
rs 4.9091
cc 9
eloc 27
nc 20
nop 1
1
<?php
2
namespace Stichoza\GoogleTranslate\Tokens;
3
4
/**
5
 * Google token generator
6
 */
7
class GoogleTokenGenerator implements TokenProviderInterface
8
{
9
    /**
10
     * Generate and return a token
11
     *
12
     * @param string $source Source language
13
     * @param string $target Target language
14
     * @param string $text Text to translate
15
     * @return mixed A token
16
     */
17
    public function generateToken($source, $target, $text)
18
    {
19
        return $this->TL($text);
20
    }
21
22
    /**
23
     * Generate a valid Google Translate request token
24
     *
25
     * @param string $a text to translate
26
     * @return string
27
     */
28
    private function TL($a)
29
    {
30
        $b = $this->generateB();
31
32
        for ($d = array(), $e = 0, $f = 0; $f < mb_strlen($a, 'UTF-8'); $f++) {
33
            $g = $this->charCodeAt($a, $f);
34
            if ( 128 > $g ) {
35
                $d[$e++] = $g;
36
            } else {
37
                if ( 2048 > $g ) {
38
                    $d[$e++] = $g >> 6 | 192;
39
                } else {
40
                    if ( 55296 == ($g & 64512) && $f + 1 < mb_strlen($a, 'UTF-8') && 56320 == ($this->charCodeAt($a, $f + 1) & 64512) ) {
41
                        $g = 65536 + (($g & 1023) << 10) + ($this->charCodeAt($a, ++$f) & 1023);
42
                        $d[$e++] = $g >> 18 | 240;
43
                        $d[$e++] = $g >> 12 & 63 | 128;
44
                    } else {
45
                        $d[$e++] = $g >> 12 | 224;
46
                        $d[$e++] = $g >> 6 & 63 | 128;
47
                    }
48
                }
49
                $d[$e++] = $g & 63 | 128;
50
            }
51
        }
52
        $a = $b;
53
        for ($e = 0; $e < count($d); $e++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
54
            $a += $d[$e];
55
            $a = $this->RL($a, '+-a^+6');
56
        }
57
        $a = $this->RL($a, "+-3^+b+-f");
58
        if (0 > $a) {
59
            $a = ($a & 2147483647) + 2147483648;
60
        }
61
        $a = fmod($a, pow(10, 6));
62
        return $a . "." . ($a ^ $b);
63
    }
64
65
    /**
66
     * Generate "b" parameter
67
     * The number of hours elapsed, since 1st of January 1970
68
     *
69
     * @return int
70
     */
71
    private function generateB()
72
    {
73
        $start = new \DateTime('1970-01-01');
74
        $now = new \DateTime('now');
75
76
        $diff = $now->diff($start);
77
78
        return $diff->h + ($diff->days * 24);
79
    }
80
81
    /**
82
     * Process token data by applying multiple operations
83
     *
84
     * @param $a
85
     * @param $b
86
     * @return int
87
     */
88
    private function RL($a, $b)
89
    {
90
        for($c = 0; $c < strlen($b) - 2; $c +=3) {
91
            $d = $b{$c+2};
92
            $d = $d >= 'a' ? $this->charCodeAt($d, 0) - 87 : intval($d);
93
            $d = $b{$c+1} == '+' ? $this->shr32($a, $d) : $a << $d;
94
            $a = $b{$c} == '+' ? ($a + $d & 4294967295) : $a ^ $d;
95
        }
96
        return $a;
97
    }
98
99
    /**
100
     * Crypto function
101
     *
102
     * @param $x
103
     * @param $bits
104
     * @return number
105
     */
106
    private function shr32($x, $bits)
107
    {
108
        if($bits <= 0) {
109
            return $x;
110
        }
111
        if($bits >= 32) {
112
            return 0;
113
        }
114
        $bin = decbin($x);
115
        $l = strlen($bin);
116
        if($l > 32) {
117
            $bin = substr($bin, $l - 32, 32);
118
        } elseif($l < 32) {
119
            $bin = str_pad($bin, 32, '0', STR_PAD_LEFT);
120
        }
121
        return bindec(str_pad(substr($bin, 0, 32 - $bits), 32, '0', STR_PAD_LEFT));
122
    }
123
124
    /**
125
     * Get the Unicode of the character at the specified index in a string
126
     *
127
     * @param string $str
128
     * @param int $index
129
     * @return null|number
130
     */
131
    private function charCodeAt($str, $index)
132
    {
133
        $char = mb_substr($str, $index, 1, 'UTF-8');
134
        if (mb_check_encoding($char, 'UTF-8')) {
135
            $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8');
136
            $result =  hexdec(bin2hex($ret));
137
            return $result;
138
        }
139
        return null;
140
    }
141
}