Completed
Push — master ( 279d4e...5d09e0 )
by Elf
02:49
created

Helper::sampleEncryption()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 15
nc 6
nop 3
dl 0
loc 28
ccs 0
cts 21
cp 0
crap 20
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace ElfSundae\Laravel\Support;
4
5
use Illuminate\Http\Request;
6
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
7
8
class Helper
9
{
10
    /**
11
     * Trim strings for the request's inputs.
12
     *
13
     * @see https://gist.github.com/drakakisgeo/3bba2a2600b4c554f836#gistcomment-1744670
14
     *
15
     * @param  \Illuminate\Http\Request  $request
16
     * @return \Illuminate\Http\Request
17
     */
18
    public static function trimRequestInputs(Request $request)
19
    {
20
        $inputs = $request->input();
21
22
        array_walk_recursive($inputs, function (&$value) {
23
            $value = trim($value);
24
        });
25
26
        $request->merge($inputs);
27
28
        return $request;
29
    }
30
31
    /**
32
     * Get file extension for MIME type.
33
     *
34
     * @param  string  $mimeType
35
     * @param  string  $prefix
36
     * @return string|null
37
     */
38
    public static function fileExtensionForMimeType($mimeType, $prefix = '')
39
    {
40
        $extension = ExtensionGuesser::getInstance()->guess($mimeType);
41
42
        if (! is_null($extension)) {
43
            if ('jpeg' == $extension) {
44
                $extension = 'jpg';
45
            }
46
47
            return $prefix.$extension;
48
        }
49
    }
50
51
    /**
52
     * Convert an iOS platform to the device model name.
53
     *
54
     * @see https://www.theiphonewiki.com/wiki/Models
55
     * @see https://support.hockeyapp.net/kb/client-integration-ios-mac-os-x-tvos/ios-device-types
56
     *
57
     * @param  string  $platform
58
     * @return string
59
     */
60
    public static function iDeviceModel($platform)
61
    {
62
        $list = [
63
            'iPhone1,1' => 'iPhone',
64
            'iPhone1,2' => 'iPhone 3G',
65
            'iPhone2,1' => 'iPhone 3GS',
66
            'iPhone3,1' => 'iPhone 4',
67
            'iPhone3,2' => 'iPhone 4',
68
            'iPhone3,3' => 'iPhone 4',
69
            'iPhone4,1' => 'iPhone 4S',
70
            'iPhone5,1' => 'iPhone 5',
71
            'iPhone5,2' => 'iPhone 5',
72
            'iPhone5,3' => 'iPhone 5c',
73
            'iPhone5,4' => 'iPhone 5c',
74
            'iPhone6,1' => 'iPhone 5s',
75
            'iPhone6,2' => 'iPhone 5s',
76
            'iPhone7,1' => 'iPhone 6 Plus',
77
            'iPhone7,2' => 'iPhone 6',
78
            'iPhone8,1' => 'iPhone 6s',
79
            'iPhone8,2' => 'iPhone 6s Plus',
80
            'iPhone8,4' => 'iPhone SE',
81
            'iPhone9,1' => 'iPhone 7',
82
            'iPhone9,2' => 'iPhone 7 Plus',
83
            'iPhone9,3' => 'iPhone 7',
84
            'iPhone9,4' => 'iPhone 7 Plus',
85
86
            'iPod1,1' => 'iPod touch',
87
            'iPod2,1' => 'iPod touch 2G',
88
            'iPod3,1' => 'iPod touch 3G',
89
            'iPod4,1' => 'iPod touch 4G',
90
            'iPod5,1' => 'iPod touch 5G',
91
            'iPod7,1' => 'iPod touch 6G',
92
93
            'iPad1,1' => 'iPad',
94
            'iPad2,1' => 'iPad 2',
95
            'iPad2,2' => 'iPad 2',
96
            'iPad2,3' => 'iPad 2',
97
            'iPad2,4' => 'iPad 2',
98
            'iPad2,5' => 'iPad mini',
99
            'iPad2,6' => 'iPad mini',
100
            'iPad2,7' => 'iPad mini',
101
            'iPad3,1' => 'iPad 3',
102
            'iPad3,2' => 'iPad 3',
103
            'iPad3,3' => 'iPad 3',
104
            'iPad3,4' => 'iPad 4',
105
            'iPad3,5' => 'iPad 4',
106
            'iPad3,6' => 'iPad 4',
107
            'iPad4,1' => 'iPad Air',
108
            'iPad4,2' => 'iPad Air',
109
            'iPad4,3' => 'iPad Air',
110
            'iPad4,4' => 'iPad mini 2',
111
            'iPad4,5' => 'iPad mini 2',
112
            'iPad4,6' => 'iPad mini 2',
113
            'iPad4,7' => 'iPad mini 3',
114
            'iPad4,8' => 'iPad mini 3',
115
            'iPad4,9' => 'iPad mini 3',
116
            'iPad5,1' => 'iPad mini 4',
117
            'iPad5,2' => 'iPad mini 4',
118
            'iPad5,3' => 'iPad Air 2',
119
            'iPad5,4' => 'iPad Air 2',
120
            'iPad6,3' => 'iPad Pro',
121
            'iPad6,4' => 'iPad Pro',
122
            'iPad6,7' => 'iPad Pro',
123
            'iPad6,8' => 'iPad Pro',
124
125
            'AppleTV2,1' => 'Apple TV 2G',
126
            'AppleTV3,1' => 'Apple TV 3G',
127
            'AppleTV3,2' => 'Apple TV 3G',
128
            'AppleTV5,3' => 'Apple TV 4G',
129
130
            'Watch1,1' => 'Apple Watch',
131
            'Watch1,2' => 'Apple Watch',
132
            'Watch2,6' => 'Apple Watch Series 1',
133
            'Watch2,7' => 'Apple Watch Series 1',
134
            'Watch2,3' => 'Apple Watch Series 2',
135
            'Watch2,4' => 'Apple Watch Series 2',
136
137
            'i386' => 'Simulator',
138
            'x86_64' => 'Simulator',
139
        ];
140
141
        return isset($list[$platform]) ? $list[$platform] : $platform;
142
    }
143
144
    /**
145
     * Get the mail homepage.
146
     *
147
     * @param  string  $address
148
     * @return string|null
149
     */
150
    public static function mailHomepage($address)
151
    {
152
        if (preg_match('#@([a-z0-9.-]+)#i', $address, $match)) {
153
            $list = [
154
                'qq.com' => 'https://mail.qq.com',
155
                'vip.qq.com' => 'https://mail.qq.com',
156
                '126.com' => 'http://www.126.com',
157
                'gmail.com' => 'https://mail.google.com',
158
                '139.com' => 'http://mail.10086.cn',
159
                'wo.cn' => 'http://mail.wo.com.cn',
160
                'sina.com' => 'http://mail.sina.com.cn',
161
                'sina.cn' => 'http://mail.sina.com.cn',
162
                'vip.sina.com' => 'http://mail.sina.com.cn',
163
            ];
164
165
            $domain = strtolower($match[1]);
166
167
            return isset($list[$domain]) ? $list[$domain] : 'http://mail.'.$domain;
168
        }
169
    }
170
171
    /**
172
     * Get the Gravatar URL.
173
     *
174
     * @param  string  $email
175
     * @param  int  $size
176
     * @param  string  $default
177
     * @param  string  $rating
178
     * @return string
179
     *
180
     * @see http://cn.gravatar.com/site/implement/images/
181
     */
182
    public static function gravatar($email, $size = 100, $default = null, $rating = null)
183
    {
184
        if (is_null($default)) {
185
            $default = config('services.gravatar.default');
186
        }
187
        if (is_null($rating)) {
188
            $rating = config('services.gravatar.rating');
189
        }
190
191
        $query = http_build_query(compact('size', 'default', 'rating'));
192
193
        return app('url')->assetFrom(
194
            config('services.gravatar.host', 'http://gravatar.com/avatar'),
195
            md5(strtolower(trim($email))).'?'.$query
196
        );
197
    }
198
199
    /**
200
     * Encrypt ASCII string via XOR.
201
     *
202
     * @param  string  $text
203
     * @param  string|null  $key
204
     * @return string
205
     */
206
    public static function sampleEncrypt($text, $key = null)
207
    {
208
        $text = (string) $text;
209
        if (is_null($key)) {
210
            $key = app('encrypter')->getKey();
211
        }
212
213
        // 生成随机字符串
214
        $random = str_random(strlen($text));
215
216
        // 按字符拼接:随机字符串 + 随机字符串异或原文
217
        $tmp = static::sampleEncryption($text, $random, function ($a, $b) {
218
            return $b.($a ^ $b);
219
        });
220
221
        // 异或 $tmp 和 $key
222
        $result = static::sampleEncryption($tmp, $key);
223
224
        return urlsafe_base64_encode($result);
225
    }
226
227
    /**
228
     * Decrypt string via XOR.
229
     *
230
     * @param  string  $text
231
     * @param  string|null  $key
232
     * @return string
233
     */
234
    public static function sampleDecrypt($text, $key = null)
235
    {
236
        if (is_null($key)) {
237
            $key = app('encrypter')->getKey();
238
        }
239
240
        $tmp = static::sampleEncryption(urlsafe_base64_decode($text), $key);
241
        $tmpLength = strlen($tmp);
242
        $result = '';
243
        for ($i = 0; $i < $tmpLength, ($i + 1) < $tmpLength; $i += 2) {
244
            $result .= $tmp[$i] ^ $tmp[$i + 1];
245
        }
246
247
        return $result;
248
    }
249
250
    /**
251
     * Do a sample XOR encryption.
252
     *
253
     * @param  string  $text
254
     * @param  string  $key
255
     * @param  \Closure|null  $callback `($a, $b, $index)`
256
     * @return string
257
     */
258
    protected static function sampleEncryption($text, $key, $callback = null)
259
    {
260
        // 对 $text 和 $key 的每个字符进行运算。
261
        // $callback 为 null 时默认进行异或运算。
262
        // $callback 参数: 第 i 位 $text, 第 i 位 $key, 下标 i
263
        // $callback 返回 false 时,结束字符循环.
264
265
        $text = (string) $text;
266
        $key = (string) $key;
267
        $keyLength = strlen($key);
268
        if (is_null($callback)) {
269
            $callback = function ($a, $b) {
270
                return $a ^ $b;
271
            };
272
        }
273
274
        $result = '';
275
        $textLength = strlen($text);
276
        for ($i = 0; $i < $textLength; $i++) {
277
            $tmp = $callback($text[$i], $key[$i % $keyLength], $i);
278
            if (false === $tmp) {
279
                break;
280
            }
281
            $result .= $tmp;
282
        }
283
284
        return $result;
285
    }
286
287
    /**
288
     * Convert an integer to a string.
289
     * It is useful to shorten a database ID to URL keyword, e.g. 54329 to 'xkE'.
290
     *
291
     * @param  int $number
292
     * @param  string|null  $characters
293
     * @return string
294
     */
295
    public static function int2string($number, string $characters = null)
296
    {
297
        $number = (int) $number;
298
        if ($number < 0) {
299
            return '';
300
        }
301
302
        if (is_null($characters)) {
303
            $characters = config('support.int2string');
304
        }
305
306
        $charactersLength = strlen($characters);
307
        $string = '';
308
309
        while ($number >= $charactersLength) {
310
            $mod = (int) bcmod($number, $charactersLength);
311
            $number = (int) bcdiv($number, $charactersLength);
312
            $string = $characters[$mod].$string;
313
        }
314
315
        return $characters[$number].$string;
316
    }
317
318
    /**
319
     * Convert an `int2string` generated string back to an integer.
320
     *
321
     * @param  string  $string
322
     * @param  string|null  $characters
323
     * @return int
324
     */
325
    public static function string2int($string, string $characters = null)
326
    {
327
        $string = strrev($string);
328
        $stringLength = strlen($string);
329
330
        if (is_null($characters)) {
331
            $characters = config('support.int2string');
332
        }
333
        $charactersLength = strlen($characters);
334
335
        $number = 0;
336
        for ($i = 0; $i < $stringLength; $i++) {
337
            $index = strpos($characters, $string[$i]);
338
            $number = (int) bcadd($number, bcmul($index, bcpow($charactersLength, $i)));
339
        }
340
341
        return $number;
342
    }
343
}
344