Completed
Pull Request — master (#37)
by
unknown
02:20
created

GoogleTokenGenerator::mb_str_split()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6667
cc 3
eloc 6
nc 3
nop 2
1
<?php
2
3
namespace Stichoza\GoogleTranslate\Tokens;
4
5
use DateTime;
6
7
/**
8
 * Google Token Generator
9
 *
10
 * Thanks to @helen5106 and @tehmaestro and few other cool guys
11
 * at https://github.com/Stichoza/google-translate-php/issues/32
12
 */
13
class GoogleTokenGenerator implements TokenProviderInterface
14
{
15
    /**
16
     * Generate and return a token
17
     *
18
     * @param string $source Source language
19
     * @param string $target Target language
20
     * @param string $text Text to translate
21
     * @return mixed A token
22
     */
23
    public function generateToken($source, $target, $text)
24
    {
25
        return $this->TL($text);
26
    }
27
28
    private function mb_str_split($str, $length = 1) 
29
    {
30
        if ($length < 1) return false;
31
        $result = array();
32
        for ($i = 0; $i < mb_strlen($str); $i += $length) {
33
            $result[] = mb_substr($str, $i, $length);
34
        }
35
        return $result;
36
    }
37
    /**
38
     * Generate a valid Google Translate request token
39
     *
40
     * @param string $a text to translate
41
     * @return string
42
     */
43
    private function TL($a)
44
    {
45
        $b = $this->generateB();
46
        $d = array_map('ord', $this->mb_str_split($a));
47
        $a = $b;
48
        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...
49
            $a = $a + $d[$e];
50
            $a = RL($a, '+-a^+6');
51
        }
52
        $a = RL($a, "+-3^+b+-f");
53
        $a  =  $a >= 0 ? $a : ($a & 0x7FFFFFFF) + 0x80000000;
54
        $a = fmod($a, pow(10, 6));
55
        return $a . "." . ($a ^ $b);   
56
    }
57
58
    /**
59
     * Generate "b" parameter
60
     * The number of hours elapsed, since 1st of January 1970
61
     *
62
     * @return double
63
     */
64
    private function generateB()
65
    {
66
        $start = new DateTime('1970-01-01');
67
        $now = new DateTime('now');
68
69
        $diff = $now->diff($start);
70
71
        return $diff->h + ($diff->days * 24);
72
    }
73
74
    /**
75
     * Process token data by applying multiple operations
76
     *
77
     * @param $a
78
     * @param $b
79
     * @return int
80
     */
81
    private function RL($a, $b)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
82
    {
83
        for ($c = 0; $c < strlen($b) - 2; $c += 3) {
84
            $d = $b{$c + 2};
85
            $d = $d >= 'a' ? $this->charCodeAt($d, 0) - 87 : intval($d);
86
            $d = $b{$c + 1} == '+' ? $this->shr32($a, $d) : $a << $d;
87
            $a = $b{$c} == '+' ? ($a + $d & 4294967295) : $a ^ $d;
88
        }
89
        return $a;
90
    }
91
92
    /**
93
     * Crypto function
94
     *
95
     * @param $x
96
     * @param $bits
97
     * @return number
98
     */
99
    private function shr32($x, $bits)
100
    {
101
        if ($bits <= 0) {
102
            return $x;
103
        }
104
        if ($bits >= 32) {
105
            return 0;
106
        }
107
        $bin = decbin($x);
108
        $l = strlen($bin);
109
        if ($l > 32) {
110
            $bin = substr($bin, $l - 32, 32);
111
        } elseif ($l < 32) {
112
            $bin = str_pad($bin, 32, '0', STR_PAD_LEFT);
113
        }
114
        return bindec(str_pad(substr($bin, 0, 32 - $bits), 32, '0', STR_PAD_LEFT));
115
    }
116
117
    /**
118
     * Get the Unicode of the character at the specified index in a string
119
     *
120
     * @param string $str
121
     * @param int $index
122
     * @return null|number
123
     */
124
    private function charCodeAt($str, $index)
125
    {
126
        $char = mb_substr($str, $index, 1, 'UTF-8');
127
        if (mb_check_encoding($char, 'UTF-8')) {
128
            $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8');
129
            $result = hexdec(bin2hex($ret));
130
            return $result;
131
        }
132
        return null;
133
    }
134
}
135